class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
print("getter of x called")
return self._x
@x.setter
def x(self, value):
print("setter of x called")
self._x = value
@x.deleter
def x(self):
print("deleter of x called")
del self._x
c = C()
c.x = 'foo' # setter called
foo = c.x # getter called
del c.x # deleter called
value = 'something'
obj.attribute = value
value = obj.attribute
del obj.attribute
如果以后要修改设置和获取,则可以使用property装饰符,而无需更改用户代码:
class Obj:
"""property demo"""
#
@property
def attribute(self): # implements the get - this name is *the* name
return self._attribute
#
@attribute.setter
def attribute(self, value): # name must be the same
self._attribute = value
#
@attribute.deleter
def attribute(self): # again, name must be the same
del self._attribute
class Obj:
def set_property(self, property, value): # don't do this
...
def get_property(self, property): # don't do this either
...
其次,这重复了两种特殊方法的用途,__setattr__和__getattr__。
第三,我们还有setattr和getattr内置函数。
setattr(object, 'property_name', value)
getattr(object, 'property_name', default_value) # default is optional
装饰器用于创建getter和setter。
例如,我们可以修改设置行为以对设置的值设置限制:
class Protective(object):
@property
def protected_value(self):
return self._protected_value
@protected_value.setter
def protected_value(self, value):
if acceptable(value): # e.g. type or range check
self._protected_value = value
class Protective(object):
def __init__(self, start_protected_value=0):
self.protected_value = start_protected_value
@property
def protected_value(self):
return self._protected_value
@protected_value.setter
def protected_value(self, value):
if value != int(value):
raise TypeError("protected_value must be an integer")
if 0 <= value <= 100:
self._protected_value = int(value)
else:
raise ValueError("protected_value must be " +
"between 0 and 100 inclusive")
@protected_value.deleter
def protected_value(self):
raise AttributeError("do not delete, protected_value can be set to 0")
使用方法:
>>> p1 = Protective(3)
>>> p1.protected_value
3
>>> p1 = Protective(5.0)
>>> p1.protected_value
5
>>> p2 = Protective(-5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
File "<stdin>", line 15, in protected_value
ValueError: protectected_value must be between 0 and 100 inclusive
>>> p1.protected_value = 7.3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 17, in protected_value
TypeError: protected_value must be an integer
>>> p1.protected_value = 101
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 15, in protected_value
ValueError: protectected_value must be between 0 and 100 inclusive
>>> del p1.protected_value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 18, in protected_value
AttributeError: do not delete, protected_value can be set to 0
试试这个:Python Property
示例代码为:
“Pythonic”的方法是不是使用“getter”和“setters”,而是使用简单的属性,如问题所示,并使用
del
来取消引用(但是名称被更改以保护无辜的。。。内置功能):如果以后要修改设置和获取,则可以使用
property
装饰符,而无需更改用户代码:(每个decorator复制并更新先前的属性对象,因此请注意,您可能应该为每个set、get和delete函数/方法使用相同的名称。)
定义上述内容后,原始设置、获取和删除是相同的:
你应该避免:
首先,上面的方法不起作用,因为您没有为将属性设置为(通常为
self
)的实例提供参数,该实例将是:其次,这重复了两种特殊方法的用途,
__setattr__
和__getattr__
。第三,我们还有
setattr
和getattr
内置函数。装饰器用于创建getter和setter。
例如,我们可以修改设置行为以对设置的值设置限制:
一般来说,我们希望避免使用
property
,而只使用直接属性。这正是Python用户所期望的。遵循最不意外的原则,除非你有一个非常令人信服的相反理由,否则你应该尽量给你的用户他们所期望的。
示范
例如,假设我们需要对象的protected属性是一个介于0和100之间的整数(包括0和100),并防止删除它,同时使用适当的消息通知用户其正确用法:
使用方法:
名字重要吗?
是的,他们确实是。
.setter
和.deleter
复制原始属性。这允许子类正确地修改行为,而不改变父类中的行为。现在,要使其生效,您必须使用各自的名称:
我不确定这在哪里有用,但是用例是如果您想要一个get、set和/或delete-only属性。可能最好坚持语义上相同、名称相同的属性。
结论
从简单的属性开始。
如果以后需要有关设置、获取和删除的功能,可以使用属性decorator添加它。
避免名为
set_...
和get_...
的函数-这就是属性的用途。相关问题 更多 >
编程相关推荐