Python中的property介绍
Python中进行OOP(面向对象程序设计)时,获取、设置和删除对象属性( attribute)的时候,常常需要限制对象属性的设置和获取,比如设置为只读、设置取值范围限制等,从而有助于类封装的灵活性,又可以使用“对象.属性”的方式操作操作类属性。为此,Python提供了两种实现机制,property() 函数和 @property 装饰器。有关这些称为Python的property(特性、特征属性)。类(class)技术本身就是一种封装手段,Python的property可以提升类封装的灵活性。
官网介绍:中文 https://docs.python.org/zh-cn/3/library/functions.html#property
英文 https://docs.python.org/3/library/functions.html#property
关于Python面向对象程序设计可参见https://blog.csdn.net/cnds123/article/details/108354860
【python中的attribute和property有什么区别
提示:attribute一般译为属性,property译为特性,但也有相反的。
attribute 包括默认的 getter/setter/deleter,触发内置的 get/set/delete 方法。
property 是特殊的 attribute,可以自定义 getter/setter/deleter 等属性,自己控制 get/set/delete 时触发的方法,也可以不定义来禁止该操作。property主要解决两个事情,如何更好的封装和访问。
早期的python中是没有property这个概念的,是在python2.2中引入的,然后在2.4中才出现了@property这样的装饰器对象的样子。
装饰器(decorator)就是把原函数传给一个新的对象或函数,然后用这个新的对象来替换原来的函数。所以当我们看到类似如下的代码:
@property
def x(self):
pass
头脑中要把它连成一个整体,它代表一个新的函数要替换原来的x(self)函数。这个新函数要干两件重要的事情:
一是执行原来的函数并返回其结果;
二是在函数执行的前后添加新的功能,这就是装饰器模式的本义。】
一、property() 函数
语法:
property(fget=None, fset=None, fdel=None, doc=None)
返回 property 属性(attribute)
说明:
fget 是获取属性值的函数。
fset 是设置属性值的函数。
fdel 是删除属性值的函数。
doc 是属性描述信息。如果省略,会把 fget 方法的文档字符串(docstring)拿来用(如果有的话)。
下面给出property() 函数示例
class Student:
def __init__(self):
self._age = None
def get_age(self):
print('获取属性时执行的代码')
return self._age
def set_age(self, age):
print('设置属性时执行的代码')
self._age = age
def del_age(self):
print('删除属性时执行的代码')
del self._age
age = property(get_age, set_age, del_age, '学生年龄')
student = Student()
# 注意要用 类名.属性.__doc__ 的形式查看属性的文档字符串
print('查看属性的文档字符串:' + Student.age.__doc__)
"""
查看属性的文档字符串:学生年龄
"""
# 设置属性
student.age = 18
"""
设置属性时执行的代码
"""
# 获取属性
print('学生年龄为:' + str(student.age))
"""
获取属性时执行的代码
学生年龄为:18
"""
# 删除属性
del student.age
"""
删除属性时执行的代码
"""
运行效果:
二、@property 装饰器
提供了比 property() 函数更简洁直观的写法。@property装饰器可以做到和内置函数property() 相同的事情。
被 @property 装饰的方法是获取属性值的方法,被装饰方法的名字会被用做 属性名。
被 @属性名.setter 装饰的方法是设置属性值的方法。
被 @属性名.deleter 装饰的方法是删除属性值的方法。
特别提示:
若省略设置属性值的方法,此时该属性变成只读属性。如果此时仍然设置属性,会抛出异常 AttributeError: can't set attribute。
如果报错 RecursionError: maximum recursion depth exceeded while calling a Python object,很可能是对象属性名和 @property 装饰的方法名重名了,一般会在对象属性名前加一个下划线 _ 避免重名,并且表明这是一个受保护的属性。
下面给出@property 装饰器示例
class Student:
def __init__(self):
self._age = None
@property
def age(self):
print('获取属性时执行的代码')
return self._age
@age.setter
def age(self, age):
print('设置属性时执行的代码')
self._age = age
@age.deleter
def age(self):
print('删除属性时执行的代码')
del self._age
student = Student()
# 设置属性
student.age = 18
"""
设置属性时执行的代码
"""
# 获取属性
print('学生年龄为:' + str(student.age))
"""
获取属性时执行的代码
学生年龄为:18
"""
# 删除属性
del student.age
"""
删除属性时执行的代码
"""
运行效果:
请注意,要确保为附加函数(additional functions)名称与原始的特征属性(original property)名称相同(本例中是age)!【方法也是函数——是类中的函数】
附录、进一步了解学习
Python中property属性的用处详解https://www.jb51.net/article/243992.htm
Python特殊属性property原理及使用方法解析https://www.jb51.net/article/197106.htm
Python的特性(property) https://www.cnblogs.com/blackmatrix/p/5646778.html
Python 从attribute到property详解https://cloud.tencent.com/developer/article/1741854