【问题标题】:What's the difference in Python between creating an attribute and declaring it in the class?在 Python 中创建属性和在类中声明它有什么区别?
【发布时间】:2012-10-13 19:01:03
【问题描述】:

这两个代码会给出两个不同的输出,为什么?

class Test:
    def __get__(self, instance, owner):
        return 42
    def __set__(self, instance, value):
        pass

class A:
    a = Test()

a = A()
print(a.a) // print 42
a.a = 0
print(a.a) // print 42

class Test:
    def __get__(self, instance, owner):
        return 42
    def __set__(self, instance, value):
        pass

class A:
    pass

a = A()
a.a = Test()
print(a.a) // print <__main__.Test object at 0xb700d6cc>
a.a = 0
print(a.a) // print 0

Python引擎中的属性是如何存储的?

【问题讨论】:

    标签: python descriptor


    【解决方案1】:

    您的Test 类不称为“属性”,它是descriptor。根据定义,描述符仅在存储在(新样式,适用于可怜的 Python 2 用户)类中时才起作用。非类对象上的描述符对象没有特殊含义,它们被视为任何其他对象。他们的__get__方法在被检索时被忽略,他们的__set__被替换时被忽略。

    【讨论】:

      【解决方案2】:

      在第一种情况下,Test 类作为 A 类的描述符,因为它定义了 __get____set__ 方法。

      如果您使用具有__get____set__ 方法的any class 作为类中的属性,则它充当类的descriptor,而不是attribute
      所以,当你给那个变量赋值时,descriptor's__set__方法被调用,当你试图访问它时,descriptor's__get__方法被调用。描述符只是通过getterssetters 提供对类属性的访问

      因此,当您在 A 类中执行 a = Test() 时,将调用描述符 __get__ 方法并返回值 42 并将其分配给它。

      而在第二种情况下,您正在实例化class Test,就像其他所有类一样。 所以,a.a 表示对类Test 实例的引用。

      【讨论】:

      • 我不同意你的表述“所以,当你在 A 类中执行 = Test() 时,...等” -- IMO 它应该be :当执行类 A 的定义时,将 a = Test() 放在类 A 的定义中会使 a 成为描述符。因此,当通过点符号对实例a 中的描述符a 进行访问时,将调用其__get__ 方法并返回值42。对象42 没有分配给任何东西,但您的句子给人的印象是42 在创建类A 时分配给A 中的标识符A
      猜你喜欢
      • 2012-03-14
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      相关资源
      最近更新 更多