Mar*_*lez 1 python properties accessor decorator python-decorators
请不要笑。生无可恋。
这是带有 getter 和 setter 的 Python 类的规范示例(来自Wikipedia):
class Student(object):
# Initializer
def __init__(self, name):
# An instance variable to hold the student's name
self._name = name
# Getter method
@property
def name(self):
return self._name
# Setter method
@name.setter
def name(self, new_name):
self._name = new_name
Run Code Online (Sandbox Code Playgroud)
现在我没有装饰器的版本:
class Student(object):
# Initializer
def __init__(self, name):
# An instance variable to hold the student's name
self._name = name
# Getter method
def name(self):
return self._name
name=property(fget=name)
# Setter method
def set_name(self, new_name):
self._name = new_name
name = property(fset=set_name)
Run Code Online (Sandbox Code Playgroud)
...除了第二个版本不起作用。如果我们实例化 Student 类,例如Bob=Student('Bob'),Bob.name 会抛出 AttributeError:unreadable 属性。
我保证,一旦我的声望达到 10k,我就会捐出 100 分给在投票开始涌入之前弯腰指出错误的善良灵魂。
您还需要命名吸气剂:
name = property(fget=name, fset=set_name)
Run Code Online (Sandbox Code Playgroud)
或者干脆
name = property(name, set_name)
Run Code Online (Sandbox Code Playgroud)
请参阅property文档。
所述@修饰语法只是语法糖; 以下表格:
@decorator_expression
def function_name(...):
...
Run Code Online (Sandbox Code Playgroud)
执行如下:
def function_name(...):
...
function_name = decorator_expression(function_name)
Run Code Online (Sandbox Code Playgroud)
请注意如何将decorator_expression部件视为可调用的,并将函数作为第一个参数传入。Aproperty()在这方面没有什么不同。
在为 定义了第一个属性之后,您的类命名空间中name就有了一个新对象name,即property对象。该对象有一个.setter()方法,它只返回属性,其中 setter 被传入的新函数替换。
因此,语法@name.setter导致调用.setter()现有property实例上的方法,并且该方法返回一个属性,它的 setter 被替换。
因此,您也可以这样拼写您的显式属性创建者:
name = property(name)
name = name.setter(set_name)
Run Code Online (Sandbox Code Playgroud)
您的版本只是将name属性(用 getter 定义)替换为一个仅定义 setter的属性,否则两者没有关系。