What's the difference in Python between creating an attribute and declaring it in the class?

StackOverflow https://stackoverflow.com/questions/12876033

  •  07-07-2021
  •  | 
  •  

質問

These two codes will give two different outputs, why ?

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

And

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

How are stored attributes in the Python engine ?

役に立ちましたか?

解決

Your Test class isn't called "attribute", it's a descriptor. Descriptors work, by definition, only when stored on a (new style, for the poor Python 2 users) class. Descriptor objects on non-class objects have no special meaning, they are treated like any other object. Their __get__ method is ignored when they are retrieved, and their __set__ is ignored when they are replaced.

他のヒント

In the first case, class Test acts a descriptor for your class A, as it defines __get__ and __set__ methods.

If you use any class having __get__, __set__ methods, as an attribute in your class, it acts as a descriptor for your class, and not as an attribute.
So, when you assign something to that variable, the descriptor's __set__ method is called, and when you try to access it, the descriptor's __get__ method is invoked. Descriptors just provides access to class's attributes through getters and setters

So, when you do a = Test() in your class A, the descriptors __get__ method is invoked and value 42 is returned and assigned to it.

Whereas in the second case, you are instantiating class Test just like every other class. So, a.a represents the reference to the instance of class Test.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top