部分内容转载自网络:
添加链接描述
class Student(object):
"""docstring for Student"""
def __init__(self, name,age,tel):
self.__name = name
self.age = age
self.tel = tel
def play(self):
print(self.__name,self.age,self.tel)
def test(self):
print(self.__name)
def main():
student = Student('张三',18,123)
student.play()
student.test()
if __name__ == '__main__':
main()
CMD:
张三 18 123
张三
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 2
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
property方法中有个四个参数 第一个参数是方法名,调用 对象.属性 时自动触发执行方法,对应下面的getter方法 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法,对应下面的setter方法 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法,对应下面的deleter方法 第四个参数是字符串,调用 对象.属性.doc ,此参数是该属性的描述信息
#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调用方式,没有括号,而是直接调用属性名即可。
class Student(object):
"""docstring for Student"""
def __init__(self, name,age,tel):
self.__name = name
self.age = age
self.tel = tel
@property
def name(self):
return self.__name
@name.setter
def name(self,name):
self.__name = name
@name.deleter
def name(self):
print('name.deleter')
del self.__name
#p = property(getname,setname)
def play(self):
print(self.__name,self.age,self.tel)
def test(self):
print(self.__name)
def main():
student = Student('张三',18,123)
student.play()
student.test()
#student.setname('李四')
#print(student.age,student.getname())
student.name = '李四'
print(student.name,student.age,student.tel)
del student.name #属性已经删除
print(student.name)
"""
CMD:
张三 18 123
张三
李四 18 123
name.deleter
Traceback (most recent call last):
File "test.py", line 49, in
main()
File "test.py", line 46, in main
print(student.name)
File "test.py", line 17, in name
return self.__name
AttributeError: 'Student' object has no attribute '_Student__name'
"""
if __name__ == '__main__':
main()
1.@property 装饰方法时,可以将方法当成类的属性的形式进行调用,操作方法如果操作实例属性一样。
2.python中的类有经典类和新式类,新式类的property属性比经典类的property属性丰富。( 如果该类继object,那么该类是新式类 ),但是在Python 3.x中取消了经典类,默认都是新式类,并且不必显式的继承object,所以如果是使用python3则不存在这个问题了。如果是python2新式类和经典类property所带的方法数量是不一样的。
1.经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
2.新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
3.由于新式类中具有三种访问方式,我们可以根据它们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除
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'