我这样做:
def set_property(property,value): def get_property(property):
要么
object.property = value value = object.property
我是Python的新手,所以我仍在探索语法,并且我想在此方面提供一些建议。
试试这个:Python属性
示例代码是:
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
使用getter和setter的pythonic方法是什么?
“ Pythonic”方式不是使用“ getters”和“ setters”,而是使用简单的属性(如问题演示所示)并del取消引用(但名称已更改以保护无辜的内建……):
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
(每个装饰器都会复制并更新先前的属性对象,因此请注意,对于每个设置,获取和删除功能/方法,你可能应该使用相同的名称。)
定义完上述内容后,原始设置,获取和删除是相同的:
obj = Obj() obj.attribute = value the_value = obj.attribute del obj.attribute
你应该避免这种情况:
首先,上面的方法不起作用,因为你没有为该属性设置为实例的实例提供参数(通常为self),该参数为:
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和getattr内置功能。
setattr
getattr
setattr(object, 'property_name', value) getattr(object, 'property_name', default_value) # default is optional
该@property装饰是创建getter和setter方法。
@property
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
通常,我们要避免property使用直接属性,而只使用直接属性。
这是Python用户所期望的。遵循最小惊奇规则,除非你有非常令人信服的相反理由,否则应尝试向用户提供他们期望的结果。
示范
例如,假设我们需要将对象的protected属性设置为0到100之间的整数(包括0和100),并防止其删除,并通过适当的消息通知用户其正确用法: 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
名称重要吗?
是的,他们愿意。.setter并.deleter复制原始财产。这允许子类在不更改父级行为的情况下正确修改行为。
class Obj: """property demo""" # @property def get_only(self): return self._attribute # @get_only.setter def get_or_set(self, value): self._attribute = value # @get_or_set.deleter def get_set_or_delete(self): del self._attribute
现在要使它起作用,你必须使用相应的名称:
obj = Obj() # obj.get_only = 'value' # would error obj.get_or_set = 'value' obj.get_set_or_delete = 'new value' the_value = obj.get_only del obj.get_set_or_delete # del obj.get_or_set # would error
我不确定这在哪里有用,但是用例是你是否需要获取,设置和/或仅删除属性。最好坚持使用具有相同名称的语义上相同的属性。
结论 从简单的属性开始。
如果以后需要围绕设置,获取和删除的功能,则可以使用属性装饰器添加它。
避免将函数命名为set_...和get_...-这就是属性的作用。
set_...
get_...