How is __mro__ different from other double underscore names?

I came across this behavior for double underlining, which I don't understand:

class A:
    pass

class B:
    pass

class C(A,B):
    __id__ = 'c'

c = C()
print(C.__mro__)  # print the method resolution order of class C
#print(c.__mro__) # AttributeError: 'C' object has no attribute '__mro__'
print(C.__id__)   # print 'c'
print(c.__id__)   # print 'c'

I know about the name for __name, which does not apply to __name__(more for overloading operator methods). __id__behaves exactly like a regular class variable, which can be accessed through the class name as well as the instance.

However, it __mro__can only be accessed through the class name, and in fact I can even explicitly enter __mro__in C:

class C(A,B):
    __mro__ = 'bla'

print(C.__mro__) # print the method resolution order of class C
print(c.__mro__) # print 'bla'

I would like to understand if this behavior is some kind of python internal manner or can be achieved in the correct python code.

[ python version 3.4.3 ]

+4
1

.

descriptors , python __dict__, . , . , AttributeError .

, , , :

#!/usr/bin/python3

class Foo(type):
    X = 10

class Bar(metaclass=Foo):
    Y = 20

baz = Bar()

print("X on Foo", hasattr(Foo, "X")) 
print("X on Bar", hasattr(Bar, "X")) 
print("X on baz", hasattr(baz, "X")) 

print("Y on Foo", hasattr(Foo, "Y")) 
print("Y on Bar", hasattr(Bar, "Y")) 
print("Y on baz", hasattr(baz, "Y")) 

:

X on Foo True
X on Bar True
X on baz False
Y on Foo False
Y on Bar True
Y on baz True

, X Foo. , Bar, baz of Bar, __dict__ Foo, __dict__ Bar baz. Python "meta".

. python?.

, , , __mro__ Foo ( ) .

. __dict__, python __dict__ , , , . , __get__. , __get__, . , , , : , , .

property. , , __mro__:

class Descriptor:
   def __get__(self, instance, owner):
      return "some value based on {}".format(instance)


class OtherFoo(type):
   Z = Descriptor()

class OtherBar(metaclass=OtherFoo):
   pass

other_baz = OtherBar()

print("Z on OtherFoo", hasattr(OtherFoo, "Z"))
print("Z on OtherBar", hasattr(OtherBar, "Z"))
print("Z on other_baz", hasattr(other_baz, "Z"))

print("value of Z on OtherFoo", OtherFoo.Z)
print("value of Z on OtherBar", OtherBar.Z)

:

Z on OtherFoo True
Z on OtherBar True
Z on other_baz False
value of Z on OtherFoo some value based on None
value of Z on OtherBar some value based on <class '__main__.OtherBar'>

, OtherBar OtherFoo Z, other_baz . , Z OtherFoo, OtherFoo.

, , . , python .

+4

Source: https://habr.com/ru/post/1649515/


All Articles