What's the difference in Python between creating an attribute and declaring it in the class?
-
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
.