我有一个情况,我的类具有自定义元类,创建时会调用该类的一个类方法,大概像这样:
class Metaclass(type):
def __new__(cls, name, bases, attrs):
...
new_class = super(Metaclass, cls).__new__(cls, name, bases, attrs)
...
new_class.get_fields() # do something
...
return new_class
class FooBar(object):
__metaclass__ = Metaclass
@classmethod
def get_fields(cls):
...
(这样的代码示例在Tastypie中有。)
问题是,如果我想要执行:
class NewBar(FooBar):
@classmethod
def get_fields(cls):
super(NewBar, cls).get_fields()
...
这个不工作是因为在调用 super
时还没有创建 NewBar
(程序流仍在元类中)。那么,有没有什么解决办法呢?
我知道可能 get_fields
方法可以成为元类的方法,但这将使继承变得更加困难(你将不得不定义新的元类和类本身,对于想要扩展这些类的开发人员来说并不好)。
(Python 2.7。)
try: super_class = NewBar; except NameError: super_class = cls; super(super_class, cls).get_fields()
这段代码怎么样? - Maciej GolNewBar
以便以最常规的方式调用super
。在您的变体中,super
调用显得比必要的更加神奇。 - user4815162342try: NewBar; except NameError: NewBar = cls; ...
将保留NameError
技巧,但明确表明我们真正寻找的是NewBar
。它仍然让我感到不安,因为它并不能 确保 它实际上找到了NewBar
。也许在那里加上assert cls.__name__ == 'NewBar'
会更好。 - user4815162342except:
中的cls
是NewBar
,但我们有两种情况:从我们的元类(NewBar.__metaclass__
)调用 - 在这里,NewBar
尚未完成构建,因此不可用作全局名称,而cls
是NewBar
类对象。第二个是NewBarDeriving.__metaclass__
,在这里,我们正在构造一个从NewBar
派生的类,因此NewBar
是一个有效的标识符,除非有人在NewBar.__metaclass__
内部创建了一个新类等。但那是巫术,不是编程。assert
很好,因为它通知程序员出现了问题。 - Maciej Gol