Python metaclass and object base class

After reading a great SO post , I tried to create a level-level metaclass:

def metaclass(future_class_name, future_class_parents, future_class_attrs): print "module.__metaclass__" future_class_attrs["bar"]="bar" return type(future_class_name, future_class_parents, future_class_attrs) __metaclass__=metaclass class Foo(object): def __init__(self): print 'Foo.__init__' f=Foo() 

This does not work (i.e., "module. Metaclass " does not print) unless I remove the base class object Foo. Why?

NOTE. I am using Python 2.6.1.

+5
source share
2 answers

Inheriting an object automatically leads to a type metaclass along with it. This overrides the __metaclass__ level specification of your module.

If the metaclass is set at the class level, the object will not override it:

 def metaclass(future_class_name, future_class_parents, future_class_attrs): print "module.__metaclass__" future_class_attrs["bar"]="bar" return type(future_class_name, future_class_parents, future_class_attrs) class Foo(object): __metaclass__ = metaclass def __init__(self): print 'Foo.__init__' f=Foo() 

See http://docs.python.org/reference/datamodel.html?highlight= metaclass # customizing-class- creating

+3
source

The specification indicates the order in which Python will look for the metaclass :

The corresponding metaclass is determined by the following rule priority:

  • If dict['__metaclass__'] exists, it is used.
  • Otherwise, if there is at least one base class, its metaclass is used (this searches for __class__ first and, if not found, uses its type).
  • Otherwise, if there is a global variable named __metaclass__ , it is used.
  • Otherwise, the classic old-style metaclass ( types.ClassType ) is used.

You will see from the above that the base class in general (no matter which base class, even if it ultimately does not inherit from object ) prevents the __metaclass__ module __metaclass__ .

+2
source

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


All Articles