Python metaclass and the object base class

喜欢而已 提交于 2019-12-12 08:53:39

问题


After reading the excellent SO post, I tried crafting a module 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 doesn't work (i.e. "module.metaclass" doesn't get printed) unless I remove the object base class of Foo. How come?

NOTE: I am using Python 2.6.1.


回答1:


Inheriting from object automatically brings the type metaclass along with it. This overrides your module level __metaclass__ specification.

If the metaclass is specified at the class level, then object won't 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-creation




回答2:


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

The appropriate metaclass is determined by the following precedence rules:

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

You will see from the above that having a base class at all (whatever the base class is, even if it does not ultimately inherit from object) pre-empts the module-level __metaclass__.



来源:https://stackoverflow.com/questions/7958212/python-metaclass-and-the-object-base-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!