问题描述
我已经阅读了一些关于Python元类的教程。我从来没有使用过,但我需要一个相对简单的东西,所有的教程似乎面向更复杂的用例。我基本上想创建一个模板类,它有一些预先指定的body,但它的基类作为参数。因为我从C ++ / D模板的想法,这里是一个例子我想要编写的代码看起来像在C ++:
I've read some tutorials on Python metaclasses. I've never used one before, but I need one for something relatively simple and all the tutorials seem geared towards much more complex use cases. I basically want to create a template class that has some pre-specified body, but takes its base class as a parameter. Since I got the idea from C++/D templates, here's an example of what the code I want to write would look like in C++:
template<class T>
class Foo : T {
void fun() {}
}
推荐答案
做一个相当简单的翻译,不使用元类,应该这样做。除了相对不复杂,因为这一点,它也可以工作,大部分不变,在Python 2& 3。
Doing a reasonably straightforward translation, which doesn't use metaclasses, should do it. Besides being relatively uncomplicated because of this, it'll also work, unchanged for the most part, in both Python 2 & 3.
from __future__ import print_function # for Py 2 & 3 compatibility
def template(class_T):
class Foo(class_T):
def fun(self):
print('%s.fun()' % self.__class__.__name__)
Foo.__name__ += '_' + class_T.__name__ # rename the subclass returned
return Foo
class Base1:
def bar(self):
print('Base1.bar()')
class Base2:
def bar(self):
print('Base2.bar()')
Foo_Base1 = template(Base1)
print('Foo_Base1 base classes:', Foo_Base1.__bases__)
Foo_Base2 = template(Base2)
print('Foo_Base2 base classes:', Foo_Base2.__bases__)
d1 = Foo_Base1()
d1.fun()
d1.bar()
d2 = Foo_Base2()
d2.fun()
d2.bar()
输出:
Foo_Base1 base classes: (<class __main__.Base1 at 0x00A79C38>,)
Foo_Base2 base classes: (<class __main__.Base2 at 0x00A79DC0>,)
Foo_Base1.fun()
Base1.bar()
Foo_Base2.fun()
Base2.bar()
在代码中(无意义地命名) template()
函数是通常称为类工厂的示例。有关详细信息,请参阅我对。
Explanation: In the code the (unimaginatively-named) template()
function is an example of what is commonly called a "class factory". For more information, see my answer to the question "What exactly is a Class Factory?".
编辑:添加了代码为每个子类创建不同的类名,返回的是@ aaronasterling的洞察如果返回的类总是具有相同的名称,则调试时的潜在混淆。
Added code to create different class names for each subclass returned—inspired by @aaronasterling's insight about potential confusion when debugging if the class returned always had the same name.
这篇关于元类来参数化继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!