Python: a problem with metaclasses combined multiple inheritance

I have two questions that convert metaclasses and multiple inheritance. First: why do I get a TypeError for the class Derived, but not for Derived2?

class Metaclass(type): pass
class Klass(object):
    __metaclass__  = Metaclass    
#class Derived(object, Klass): pass # if I uncomment this, I get a TypeError

class OtherClass(object): pass
class Derived2(OtherClass, Klass): pass # I do not get a TypeError for this

The exact error message is:

TypeError: error when calling metaclass bases. Cannot create consistent method resolution (MRO) order for base object

Second question: why superdoesnโ€™t work in this case (if I use __init__instead __new__, superit works again):

class Metaclass(type):
    def __new__(self, name, bases, dict_):
        return super(Metaclass, self).__new__(name, bases, dict_)
class Klass(object):
    __metaclass__  = Metaclass

There I get:

TypeError: an error occurred while invoking a metaclass database type. new (X): X is not an object of type (str)

I am using Python 2.6.

+3
4

, __new__ staticmethod, classmethod ...:

>>> class sic(object):
...   def __new__(cls, *x): return object.__new__(cls, *x)
... 
>>> type(sic.__dict__['__new__'])
<type 'staticmethod'>

( -) : A B , B A. :

>>> class cis(sic): pass
... 
>>> class oops(sic, cis): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    Cannot create a consistent method resolution
order (MRO) for bases sic, cis

MRO , , , , x y, x y. . , : (, , , ), x y, . : object -, - ? object ( ;-) , ?

+7

MRO python - , " ". , , python , . ( .)

, , , __new__. - . :

class Metaclass(type):
    def __new__(cls, name, bases, dictn):
        return type.__new__(cls, name, bases, dictn)
+3

self __new__ :

class Metaclass(type):
    def __new__(self, name, bases, dict_):
        return super(Metaclass, self).__new__(self, name, bases, dict_)

class Klass(object):
    __metaclass__  = Metaclass

, , , type.__new__ , , self.

0

?

class Derived(object, Klass):

.

class Derived(Klass):

.

0

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


All Articles