【问题标题】:Different results on applying the same property decorator应用相同的属性装饰器的不同结果
【发布时间】:2018-02-04 14:21:06
【问题描述】:

当我将 property 装饰器应用于类定义中的方法时,python 接受带有 @decorator 但不带有显式语法的版本。以下是代码:

>>> class Person:
...     first_name = property()
...     def first_name(self):
...         pass
...     first_name = first_name.getter(first_name)
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in Person
AttributeError: 'function' object has no attribute 'getter'

这个结果我能理解——虽然first_name被定义为property对象,然后它被重新定义为一个没有getter方法的函数对象。 但是接下来的代码是如何工作的-

>>> class Person:
...     first_name = property()
...     @first_name.getter
...     def first_name(self):
...         pass
... 
>>> 

我只做了语法上的改变,但这个版本没有错误。为什么?

【问题讨论】:

    标签: python python-3.x properties


    【解决方案1】:

    在第一个示例中,您使用函数覆盖了first_name 中的属性。默认情况下,函数没有getter 属性。 def 是语法糖(有点),例如:

    first_name = property()
    
    # def replacement
    first_name = lambda self: None
    
    first_name = first_name.getter(first_name)
    

    第二个使用装饰器,所以first_nameproperty().getter(func) 返回的。哪个是属性。

    这一切的正常风格是:

    @property
    def first_name(self):
        pass
    

    与以下内容大致相同:

    first_name = property(lambda self: None)
    

    getter/setter 样式之所以有效,是因为在将函数分配给命名空间之前引用了装饰器(实际上,在使用装饰器时,没有将函数分配给命名空间的中间步骤)。

    first_name = property()
    # this is effectively how the function definition and decorator code is executed
    first_name = first_name.getter(lambda self: None)
    

    【讨论】:

    • 我知道正常的风格 - 我正在阅读 Python 食谱中的一个示例。我不明白的是,我所说的两种方法在语法上都是等效的,但会产生不同的结果。使用@时,为什么没有名字冲突?
    • 因为first_name作为属性在被装饰器覆盖之前被引用。
    • 照书看,我可以在getter之后有一个setter方法@first_name.setter。如果作为 getter 装饰器的结果,first_name 现在是修改后的方法名称,那么 setter 语法将如何工作? first_name 现在不是 property 对象。 @first_name.setter怎么又引用了属性对象?
    • property.getterproperty.setter 都返回一个属性。只要first_name 是一个属性,那么就没有问题。
    • 我猜first_name 在应用 getter 后仍然是 property
    猜你喜欢
    • 2011-12-24
    • 1970-01-01
    • 2019-12-11
    • 2016-11-25
    • 2020-08-12
    • 2023-04-10
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多