我想在创建类的过程中自动运行任何派生类的基类中定义的类方法。例如:
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 的元类,而不必为此明确地设置它。
答案 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