Python元类在派生类上自动运行类方法

时间:2012-06-21 02:57:22

标签: python metaprogramming metaclass

我想在创建类的过程中自动运行任何派生类的基类中定义的类方法。例如:

class Base(object):
  @classmethod
  def runme():
    print "I am being run"

  def __metclass__(cls,parents,attributes):
    clsObj = type(cls,parents,attributes)
    clsObj.runme()
    return clsObj


class Derived(Base):
  pass:

这里发生的是当创建Base时,'runme()''将会触发。但是在创建Derived时没有任何反应。

问题是:如何在创建 Derived 时激活''runme()''。

这是我到目前为止所想的:如果我明确地将派生的元类设置为 Base ,它将会起作用。但我不希望这种情况发生。我基本上希望 Derived 使用 Base 的元类,而不必为此明确地设置它。

4 个答案:

答案 0 :(得分:2)

this answer。基本上,在调用type(cls,parents,attributes)时,您正在创建一个类,而不传递有关该类的元类的信息。因此,返回的类没有您想要的元类;相反,它有元类type。 (具有讽刺意味的是,通过定义__metaclass__来执行此操作,您明确地使您的类具有该元类。)而不是直接调用类型,您需要调用{{1} },其中meta是元类。

但是,当您定义type.__new__(meta, cls, parents, attrs)内联时,无法实现此目的。从__metaclass__方法内部,您无法引用该方法,因为它是尚未定义的类的方法。你想做类似

的事情
__metaclass__

。 。 。但是你没有任何东西可以让def __metaclass__(cls, bases, attrs): type.__new__(metaclassGoesHere, cls, bases, attrs) 让它做正确的事情,因为你试图引用的是你试图引用它的方法。

所以只需在外部定义你的元类。

答案 1 :(得分:0)

将您的runme()重命名为__init__(self)不要覆盖__init__()方法,并且每次创建{{1}的实例时都会调用它}}

Derived

复制并粘贴它,它将打印class Base(object): def __init__(self): print "I am being run" class Derived(Base): pass dummy_instance = Derived()

答案 2 :(得分:0)

试试这个,

class MyMetaclass(type): 

    def __new__(cls, name, bases, dct):

        runme()

        return super(MyMetaclass, cls).__new__(cls, name, bases, uppercase_attr)

答案 3 :(得分:0)

如果您想在创建课程时执行某些操作,则必须使用__init__的{​​{1}}方法执行此操作。

__metaclass__

打印哪些:

class foo(object):
    @classmethod
    def method(cls):
        print 'I am being run by', cls.__name__

    class __metaclass__(type):
        def __init__(self, *args, **kwargs):
            type.__init__(self, *args, **kwargs)
            self.method()

class bar(foo): pass