一.内置装饰器
1.@property装饰器是python内置的装饰器
1.1.是把类中的一个方法变为类中的一个属性,并且使定义属性和修改现有属性变的更容易
2.@property源码
class C(object):
@property
def x(self):
"I am the 'x' property."
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
3.这装饰器会把定义新属性和对现有的属性的修改变的更简单
3.1.那么传统的方法在绑定属性和访问属性时是什么样的呢?
class UserInfo(object):
def get_name(self):
"""通过类的方法访问类中的属性"""
return self.__name
def set_name(self, name):
"""通过外部传参的方式绑定属性"""
self.__name = name
if __name__ == '__main__':
user = UserInfo()
# 绑定name属性
user.set_name([u"超哥", u"linux超"])
print(u"我的名字是:", user.get_name())
4.这种方式在绑定属性,获取属性时显的很繁琐,而且无法保证数据的准确性
4.1.从执行结果看来名字应该是个字符串才对,然而输出结果却是个列表,这并不符合实际规则
4.2.而且也没有通过直接访问属性,修改属性的方式那么直观
5.对代码稍作改动并使用@property装饰器来实现
class UserInfo(object):
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
if isinstance(name, str):
self.__name = name
else:
raise TypeError(u"The name must be str")
if __name__ == '__main__':
user = UserInfo()
# 绑定属性
user.name = u"linux超"
print("我的名字是", user.name)
user.name = [u"linux超", u"超哥"]
print(u"我的名字是", user.name)
6.经过优化后的代码可以看到当绑定的属性并非是一个字符串类型时,就会报错
6.1.而且可以直接通过类似访问属性的方式来绑定属性,访问属性,这样就更加直观
7.注意@name.setter中name这个名字极其被他修饰的方法名字
7.1.与@property修改的方法名必须保持一致,否则会报错
8.其中@name.setter装饰器是因为使用了@property后他本身创建的装饰器
9.其实@perproty装饰器并不仅仅只用来绑定属性和访问属性
9.1.还可以用来在类的外部访问私有成员属性
10.先来看个类的外部直接访问私有成员的实例
class UserInfo(object):
def __init__(self, name, age):
self.__name = name
self.__age = age
if __name__ == '__main__':
user = UserInfo(u'linux超', 18)
print(user.__name)
11.程序是没办法运行成功的,因为python不允许你在类的外部访问类中的私有成员
11.1.这么做其实是为了保护数据的安全性
11.那么这时候可以使用@property装饰器来访问类的属性,这样就能访问类的私有成员属性
12.相对于绑定属性来说这种方式用的比较多,当不想子类继承父类时,防止子类修改父类的属性
12.1.那么完全就可以使用这种方法来避免属性被修改,而且在子类和类的外部还可以正常访问这个私有属性
class UserInfo(object):
def __init__(self, name):
self.__name = name
@property
def name(self):
"""通过类的方法访问类中的私有属性"""
return self.__name
if __name__ == '__main__':
user = UserInfo(u'linux超')
print(u"获取name属性:", user.name)
二.总结
1.被此装饰器装饰的方法不能传递任何除self外的其他参数
2.同时使用@property和@x.setter时
2.1.需要保证以及被@x.setter修改的方法名字与@property修改的方法名字必须保持一致