含糖和不含糖的性质

时间:2013-05-07 21:11:23

标签: python properties decorator python-decorators accessor

请不要笑。我很绝望。

以下是带有getter和setter(来自Wikipedia)的python类的规范示例:

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

现在我的版本没有装饰器:

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)

...除了第二个版本不起作用。如果我们实例化Student类,例如Bob=Student('Bob'),Bob.name抛出AttributeError:不可读的属性。

我保证,一旦我的声望达到10k,我就会捐出100分给那些在暗中投票开始涌入前指出这个虫子的灵魂。

2 个答案:

答案 0 :(得分:4)

你也需要为getter命名:

name = property(fget=name, fset=set_name)

或只是

name = property(name, set_name)

请参阅property documentation

@装饰器语法只是语法糖;以下表格:

@decorator_expression
def function_name(...):
    ...

执行为:

def function_name(...):
    ...
function_name = decorator_expression(function_name)

注意decorator_expression部分如何被视为可调用,并将函数作为第一个参数传入。 property()在这方面没有什么不同。

在为name定义第一个属性后,您的类名称空间中有一个 new 对象name,即property对象。该对象有一个.setter()方法,它只返回属性,并将setter替换为传入的新函数。

因此,语法@name.setter会导致调用现有.setter()实例上的property方法,并且该方法返回一个属性,并将其setter替换。

所以,你也可以拼写你的显性属性创建者:

name = property(name)
name = name.setter(set_name)

您的版本只是将name属性(使用getter定义)替换为仅定义一个setter的属性,否则两者没有关系。

答案 1 :(得分:0)

getter和setter在python中有点毫无意义,除非他们实际上在做事。

class kid:
    def __init__(self,name):
        self.name = name


>>>bill = kid('bill')
>>>bill.name = 'johnny' #is good enough
>>>bill.name
johnny
>>>bill.job = 'student'
>>>bill.job
student