Python 元类和对象基类

发布于 2024-12-13 03:07:26 字数 630 浏览 0 评论 0原文

在阅读了优秀的 SO 帖子后,我尝试制作一个模块level 元类:

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()

除非我删除 Foo 的 object 基类,否则这不起作用(即“module.metaclass”不会被打印)。怎么会?

注意:我使用的是 Python 2.6.1。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅唱々樱花落 2024-12-20 03:07:26

object继承会自动带来type元类。这会覆盖您的模块级别 __metaclass__ 规范。

如果在类级别指定元类,则 object 将不会覆盖它:

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()

请参阅 http://docs.python.org/reference/datamodel.html?highlight=元类#customizing-class-creation

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

野侃 2024-12-20 03:07:26

规范 指定 Python 查找元类的顺序

适当的元类由以下优先级决定
规则:

  • 如果 dict['__metaclass__'] 存在,则使用它。
  • 否则,如果有
    至少一个基类,使用它的元类(这会寻找一个
    首先是 __class__ 属性,如果找不到,则使用其类型)。
  • 否则,如果名为 __metaclass__ 的全局变量存在,则使用它。
  • 否则,将使用旧式经典元类 (types.ClassType)。

从上面你会看到,拥有一个基类(无论基类是什么,即使它最终不是从object继承)会抢占模块 -级别__metaclass__

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__.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文