Properties
Rather than only acting as a proxy to the standard namespace dictionary, properties allow attributes to be powered by methods that can access the full power of Python. Typically, properties are defined using the built-in @property decorator function. When applied to a method, it forces the method to be called whenever the function’s name is accessed as an attribute name.
当@property被应用到一个函数时,在任何这个函数名被当做属性访问的地方,该方法将被调用。(也就是说@property可以使一个方法具有属性访问的特性,尤其是对私有属性的getter和setter方法适用)
class Person:
... def __init__(self, first_name, last_name):
... self.first_name = first_name
... self.last_name = last_name
... @property
... def name(self):
... return '%s, %s' % (self.last_name, self.first_name)
...
>>> p = Person('Marty', 'Alchin')
>>> p.name
'Alchin, Marty'
>>> p.name = 'Alchin, Martin' # Update it to be properly legal
Traceback (most recent call last):
...
AttributeError: can't set attribute
|
That last error isn’t terribly descriptive, but basically properties defined this way only retrieve attribute values, not set them. Function calls are only one way, so in order to set the value, we’ll need to add
后面的错误描述并不确切。property只能被用来获取属性的值,而不是设置属性值。函数调用是唯一的一种方法来设定属性值。所以我们需要添加一个新的函数来做这方面的事情。
another method that handles that side of things. This new method would accept another variable: the value that should be set on the attribute.
新函数需要接收另一个参数-被用来设置为属性值的参数。
In order to mark the new method as the setter for a property, it’s decorated much like the getter property. Rather than using a built-in decorator, though, the getter gains a setter attribute that can be used to decorate the new method. This fits with the typical noun-based naming convention of decorators, while also describing which property will be managed.
为了标示新的函数是属性的setter方法,可以将其类似于getter一样进行修饰。这里的修饰符不是built-in的,而是得益于我们前面定义的getter修饰方法的一个属性(setter)。这符合修饰符以名词为基础的要求,并能够很好的说明哪个属性在该方法中被设置。
>>> class Person:
... def __init__(self, first_name, last_name):
... self.first_name = first_name
... self.last_name = last_name
... @property
... def name(self):
... return '%s, %s' % (self.last_name, self.first_name)
... @name.setter
... def name(self, value):
... return '%s, %s' % (self.last_name, self.first_name)
...
>>> p = Person('Marty', 'Alchin')
>>> p.name
'Alchin, Marty'
>>> p.name = 'Alchin, Martin' # Update it to be properly legal
>>> p.name
'Alchin, Martin'
|
Just make sure that the setter method is named the same as the original getter method or it won’t work property. The reason for this is that name.setter doesn’t actually update the original property with the setter method. Instead, it copies the getter onto the new property and assigns them both to the name given to the setter method. Exactly what this means behind the scenes will be explained better in the next section on descriptors.
切记setter方法和getter方法的名字必须是相同的,否则将不会起作用。这样做的原因是.....
In addition to getting and setting values, a property can also delete the current value, using a decorator similar to the setter. By applying name.deleter to a method that only accepts the usual self, you can use that method to delete values from the attribute. For the Person class shown here, that means clearing out both first_name and last_name together.
除了能够get和set属性之外,还可以使用类似于setter的修饰符删除一个属性值。使用name.deleter修饰一个只有self参数的函数,你就可以使用该函数执行属性值的删除操作。
>>> class Person:
... def __init__(self, first_name, last_name):
... self.first_name = first_name
... self.last_name = last_name
... @property
... def name(self):
... return '%s, %s' % (self.last_name, self.first_name)
... @name.setter
... def name(self, value):
... return '%s, %s' % (self.last_name, self.first_name)
... @name.deleter
... def name(self):
... del self.first_name
... del self.last_name
...
>>> p = Person('Marty', 'Alchin')
>>> p.name
'Alchin, Marty'
>>> p.name = 'Alchin, Martin' # Update it to be properly legal
>>> p.name
'Alchin, Martin'
>>> del p.name
>>> p.name
Traceback (most recent call last):
...
AttributeError: 'Person' object has no attribute 'last_name'
|
阅读(2063) | 评论(1) | 转发(0) |