python内置装饰器@property
2019-07-24 09:14:59来源:博客园 阅读 ()
前言
今天来说一下@property装饰器,这是个python内置的装饰器,主要是作用是把类中的一个方法变为类中的一个属性,并且使定义属性和修改现有属性变的更容易
我们可以看一下@property源码中给的实例和解释
1 Decorators make defining new properties or modifying existing ones easy: 2 3 4 class C(object): 5 @property 6 def x(self): 7 "I am the 'x' property." 8 return self._x 9 10 @x.setter 11 def x(self, value): 12 self._x = value 13 14 @x.deleter 15 def x(self): 16 del self._x
没错,龟叔给的解释就是这个装饰器会把定义新属性和对现有的属性的修改变的更简单,那么传统的方法在绑定属性和访问属性时是什么样的呢?
实例
1 """ 2 ------------------------------------ 3 @Time : 2019/7/4 20:57 4 @Auth : linux超 5 @File : python_property.py 6 @IDE : PyCharm 7 @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 @QQ : 28174043@qq.com 9 @GROUP: 878565760 10 ------------------------------------ 11 """ 12 13 14 class UserInfo(object): 15 16 def get_name(self): 17 """通过类的方法访问类中的属性""" 18 return self.__name 19 20 def set_name(self, name): 21 """通过外部传参的方式绑定属性""" 22 self.__name = name 23 24 25 if __name__ == '__main__': 26 user = UserInfo() 27 # 绑定name属性 28 user.set_name(["超哥", "linux超"]) 29 print("我的名字是:", user.get_name())
执行结果
我的名字是: [’超哥’, ‘linux超’]
Process finished with exit code 0
这种方式在绑定属性,获取属性时显的很是繁琐,而且无法保证数据的准确性,从执行结果看来,名字应该是个字符串才对,然而输出结果却是个列表,这并不符合实际规则
而且也没有通过直接访问属性,修改属性的方式那么直观
我们对代码稍作改动,并使用@property装饰器来实现
1 """ 2 ------------------------------------ 3 @Time : 2019/7/4 22:02 4 @Auth : linux超 5 @File : python_class.py 6 @IDE : PyCharm 7 @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 @QQ : 28174043@qq.com 9 @GROUP: 878565760 10 ------------------------------------ 11 """ 12 13 14 class UserInfo(object): 15 @property 16 def name(self): 17 return self.__name 18 19 @name.setter 20 def name(self, name): 21 if isinstance(name, str): 22 self.__name = name 23 else: 24 raise TypeError("The name must be str") 25 26 27 if __name__ == '__main__': 28 user = UserInfo() 29 # 绑定属性 30 user.name = "linux超" 31 print("我的名字是", user.name) 32 user.name = ["linux超", "超哥"] 33 print("我的名字是", user.name)
执行结果
我的名字是 linux超 Traceback (most recent call last): File "D:/LingMengPython16/LingMengPython16/cnblogs/python_class.py", line 32, in <module> user.name = ["linux超", "超哥"] File "D:/LingMengPython16/LingMengPython16/cnblogs/python_class.py", line 24, in name raise TypeError("The name must be str") TypeError: The name must be str Process finished with exit code 1
经过优化后的代码我们可以看到当绑定的属性并非是一个字符串类型时,就会报错,而且我们可以直接通过类似访问属性的方式来绑定属性,访问属性,这样就更加直观了
这里有个点需要注意,@name.setter中name这个名字极其被他修饰的方法名字与@property修改的方法名必须保持一致,否则会报错
其中@name.setter装饰器是因为使用了@property后他本身创建的装饰器
其实呢,我觉得@perproty装饰器并不仅仅只用来绑定属性和访问属性,还可以用来在类的外部访问私有成员属性
先来看个类的外部直接访问私有成员的实例
1 """ 2 ------------------------------------ 3 @Time : 2019/7/4 20:57 4 @Auth : linux超 5 @File : python_property.py 6 @IDE : PyCharm 7 @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 @QQ : 28174043@qq.com 9 @GROUP: 878565760 10 ------------------------------------ 11 """ 12 13 14 class UserInfo(object): 15 16 def __init__(self, name, age): 17 self.__name = name 18 self.__age = age 19 20 if __name__ == '__main__': 21 user = UserInfo('linux超', 18) 22 print(user.__name)
执行结果
Traceback (most recent call last): File "D:/LingMengPython16/LingMengPython16/cnblogs/python_property.py", line 22, in <module> print(user.__name) AttributeError: 'UserInfo' object has no attribute '__name' Process finished with exit code 1
没错,程序是没办法运行成功的,因为python不允许你在类的外部访问类中的私有成员,这么做其实是为了保护数据的安全性
那么这时候我们也可以使用@property装饰器来访问类的属性
1 """ 2 ------------------------------------ 3 @Time : 2019/7/4 20:57 4 @Auth : linux超 5 @File : python_property.py 6 @IDE : PyCharm 7 @Motto: Real warriors,dare to face the bleak warning,dare to face the incisive error! 8 @QQ : 28174043@qq.com 9 @GROUP: 878565760 10 ------------------------------------ 11 """ 12 13 14 class UserInfo(object): 15 16 def __init__(self, name): 17 self.__name = name 18 19 @property 20 def name(self): 21 """通过类的方法访问类中的私有属性""" 22 return self.__name 23 24 if __name__ == '__main__': 25 user = UserInfo('linux超') 26 print("获取name属性:", user.name)
执行结果
获取name属性: linux超
Process finished with exit code 0
这样就能访问类的私有成员属性了
那么其实我个人认为,相对于绑定属性来说这种方式用的比较多,当你不想子类继承父类时,防止子类修改父类的属性,那么你完全就可以使用这种方法来避免属性被修改,而且在子类和类的外部还可以正常访问这个私有属性
总结
@property装饰器主要用来改变一个方法为一个属性,且需要注意几点
1. 被此装饰器装饰的方法不能传递任何除self外的其他参数
2.当同时使用@property和@x.setter时 需要保证x以及被@x.setter修改的方法名字与@property修改的方法名字必须保持一致
原文链接:https://www.cnblogs.com/linuxchao/p/linuxchao-property.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash