0
点赞
收藏
分享

微信扫一扫

python中对私有属性的操作:property的使用


      ​ Python中之所以给方法,属性进行私有化,一是为了封装性。二是为了程序的安全性。python中可以使用__定义私有属性,私有属性类外和子类都不能直接操作访问,但是实际开发中私有属性也不是一层不变的。所以要给私有属性提供外部能够操作的方法。

1.property属性的定义与使用

     ​  property的用法其实就是在方法上应用装饰器,在方法上面添加 @property的方式。具体啥事装饰器后面介绍。实现功能就是在类中定义值为property对象的类属性,换句话说就是可以将方法封装成类属性,用调用类属性的方式进行调用方法,而且property本身也带有方法。

2.property对类的私有属性进行操作,类似java中的getter/setter

     一般为了程序安全而封装的原因,python中会有一些私有属性,无法直接访问,那么这个时候如果操作他呢,就需要类给提供相应的getter/setter方法。

2.1.通过自定义get,set方法,调用方法的形式去对私有属性进行操作

#1.通过自定义get,set方法,调用方法的形式去对私有属性进行操作
class Person(object):
def __init__(self, name, age):
self.name = name
self.__age = age

#定义对私有属性的get方法,获取私有属性
def getAge(self):
return self.__age

#定义对私有属性的重新赋值的set方法,重置私有属性
def setAge(self,age):
self.__age = age

person1 = Person("tom",19)
person1.setAge(20)
print(person1.name,person1.getAge()) #tom 20

2.通过调用property属性对set,get方法进行了封装。然后操作私有属性

#2.通过调用property属性对set,get方法进行了封装。然后操作私有属性
class Student(object):
def __init__(self, name, age):
self.name = name
self.__age = age

#定义对私有属性的get方法,获取私有属性
def getAge(self):
return self.__age

#定义对私有属性的重新赋值的set方法,重置私有属性
def setAge(self,age):
self.__age = age

p = property(getAge,setAge) #注意里面getAge,setAge不能带()

s1 = Student("jack",22)
s1.p = 23 #如果使用=,则会判断为赋值,调用setAge方法。
print(s1.name,s1.p) #jack 23 ,直接使用s1.p会自动判断会取值,调用getAge
print(s1.name,s1.getAge()) #jack 23,这个时候set,get方法可以单独使用。

尖叫提示:property方法中有个四个参数


  • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法,对应下面的getter方法
  • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法,对应下面的setter方法
  • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法,对应下面的deleter方法
  • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

 3.直接使用property标注同名函数的形式。这是最终开发中常用的方法。

#3.上面两种还是太麻烦,直接使用property标注同名函数的形式。这是最终开发中常用的方法。
class Teacher(object):
def __init__(self, name, age,speak):
self.name = name
self.__age = age
self.__speak = speak


@property #注意1.@proterty下面默认跟的是get方法,如果设置成set会报错。
def age(self):
return self.__age

@age.setter #注意2.这里是使用的上面函数名.setter,不是property.setter.
def age(self,age):
if age > 150 and age <=0: #还可以在setter方法里增加判断条件
print("年龄输入有误")
else:
self.__age = age

@property
def for_speak(self): #注意2.这个同名函数名可以自定义名称,一般都是默认使用属性名。
return self.__speak

@for_speak.setter
def for_speak(self, speak):
self.__speak = speak



t1 = Teacher("herry",45,"Chinese")
t1.age = 38 #注意4.有了property后,直接使用t1.age,而不是t1.age()方法了。
t1.for_speak = "English"

print(t1.name,t1.age,t1.for_speak) #herry 38 English

尖叫提示:


  1. ​.@property​​成为属性函数,可以对属性赋值时做必要的检查,比如在setter方法里加过滤判断条件。此外相比自定义的get和set方法,property保证了代码的短小精悍,对私有属性的操作代码格式化模块化。
  2. @property只有一个参数self,且要有返回值,所以一般定义属性的get方法。
  3. 注意@property调用方式,没有括号,而是直接调用属性名即可。

3.property对方法的使用


  1. @property 装饰方法时,可以将方法当成类的属性的形式进行调用,操作方法如果操作实例属性一样。
  2. python中的类有​​经典类​​和​​新式类​​,​​新式类​​的property属性比​​经典类​​的property属性丰富。( 如果该类继object,那么该类是新式类 ),但是在Python 3.x中取消了经典类,默认都是新式类,并且不必显式的继承object,所以如果是使用python3则不存在这个问题了。如果是python2新式类和经典类property所带的方法数量是不一样的。

#coding=utf-8
# ############### 定义 ###############
class Goods:
"""python3中默认继承object类
以python2、3执行此程序的结果不同,因为只有在python3中才有@xxx.setter @xxx.deleter
"""
@property
def price(self):
print('@property')

@price.setter #注意这里是price.setter,而不是property.setter
def price(self, value):
print('@price.setter')

@price.deleter
def price(self):
print('@price.deleter')

# ############### 调用 ###############
obj = Goods()
obj.price #@property, 自动执行 @property 修饰的 price 方法,并获取方法的返回值
obj.price = 123 #@price.setter,自动执行 @price.setter 修饰的 price 方法,并将123赋值给方法的参数
del obj.price #@price.deleter 自动执行 @price.deleter 修饰的 price 方法,注意这里的执行方式del obj.price

尖叫提示: 


  • 经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
  • 新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法

由于新式类中具有三种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除

class Goods(object):

def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8

@property
def price(self):
# 实际价格 = 原价 * 折扣
new_price = self.original_price * self.discount
return new_price

@price.setter
def price(self, value):
self.original_price = value #在这里修改原来类属性original_price

@price.deleter #注意这个deleter修饰器生效的前提是在该方法体内增加了del删除属性的操作,属性才会真的被删除。
def price(self):
del self.original_price #这个才是实际删除属性的操作。
obj = Goods()
print(obj.price) # 获取商品价格,80
obj.price = 200 # 修改商品原价,160
print(obj.price) #160
print(obj.original_price) #200
del obj.price # 删除商品原价,这里original_price属性被删除了,所以下面调用会报错。
print(obj.price) #AttributeError: 'Goods' object has no attribute 'original_price'

统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。


举报

相关推荐

0 条评论