6

我已经阅读了一些关于 Python 元类的教程。我以前从未使用过,但我需要一个相对简单的东西,而且所有教程似乎都针对更复杂的用例。我基本上想创建一个模板类,它具有一些预先指定的主体,但将其基类作为参数。因为我是从 C++/D 模板中得到这个想法的,所以这里有一个我想编写的代码在 C++ 中的示例:

template<class T>
    class Foo : T {
        void fun() {}
    }
4

2 回答 2

10

虽然它当然可以用元类来完成,但你可以在没有它们的情况下做你想做的事,因为在 Python 中,类本身就是对象。这意味着——令人惊讶的是——基本上只需要几乎一对一的 C++ 代码翻译。除了因此相对简单之外,它还可以在 Python 2 和 3 中无需修改即可工作。

def template(class_T):
    """Factory function to create subclasses of class_T."""

    class Foo(class_T):
        def fun(self):
            print('%s.fun()' % self.__class__.__name__)

    Foo.__name__ += '_' + class_T.__name__  # rename the subclass to reflect its heritage
    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: {}'.format(Foo_Base1.__bases__))

Foo_Base2 = template(Base2)
print('Foo_Base2 base classes: {}'.format(Foo_Base2.__bases__))

subclass1 = Foo_Base1()
subclass1.fun()
subclass1.bar()
subclass2 = Foo_Base2()
subclass2.fun()
subclass2.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()函数中的代码是通常称为类工厂工厂模式实现的示例。所以,顺便说一句,你可能会找到我对什么是类工厂这个问题的回答?内容丰富。

Edit: Added code to create different class names for each subclass returned—which was inspired by @aaronasterling's insight (in a now deleted comment) about potential confusion when debugging if the class manufactured always has the same name.

于 2010-10-06T21:43:04.817 回答
0

This is meaningless in Python, since it does not have templates. My understanding of parameterized templates in C++ (which is rather vague, since it is many years since I have looked at them), is that it acts like a class factory, and can create a subclass of whatever class you give it that has additional methods or attributes added.

In Python you can do this with a factory function that takes a class and returns a new class at runtime:

In [1]: def subclassFactory(cls):
   ...:     class Foo(cls):
   ...:         def fun(self):
   ...:             return "this is fun"
   ...:     return Foo
   ...: 

In [2]: class A(object):
   ...:     pass
   ...: 

In [5]: C = subclassFactory(A)

In [6]: C
Out[6]: <class '__main__.Foo'>
In [7]: c = C()
In [9]: c.fun()
Out[9]: 'this is fun'
In [10]: isinstance(c, A)
Out[10]: True
于 2010-10-06T21:48:53.240 回答