Python,如何灵活创建子类?

时间:2013-08-30 06:37:06

标签: python

详细问题是我有很多课程,比如A,B,C,D ...... Z,它们都来自'Base'。它们都有方法set_value。现在我需要有一些子类来覆盖A ... Z的set_value,新set_value的实现对于所有人都是相同的。从理论上讲,我可以做类似AA(A),BB(B)类......但是它很乏味而且不紧凑,我不确定A ... Z中的一个或全部是否需要一个子类,我只想要在创建子类的对象时创建它。

在C ++中,我可以通过模板轻松完成此任务:

template<class T>
class CCustom : public T
{
};
CCustom<vector<int> > obj1;
CCustom<list<char> > obj2;

在这里添加一些演示Python脚本以帮助解释我的问题:

class Base:
def set_value(self):
    pass

class A(Base):
    def set_value(self):
        print('A.set_value')

class B(Base):
    def set_value(self):
        print('B.set_value')

class C(Base):
    def set_value(self):
        print('C.set_value')


def more_set_value():
    print('all subclasses do this')

class AA(A):
    def set_value(self):
        more_set_value()
        super().set_value()

class BB(B):
    def set_value(self):
        more_set_value()
        super().set_value()

class CC(C):
    def set_value(self):
        more_set_value()
        super().set_value()

a = AA()
b = BB()
c = CC()

a.set_value()
b.set_value()
c.set_value()

你可以看到AA,BB和CC几乎相同。当有数百种类需要放入我的项目时,这很无聊。我认为必须有一种方法来编写工厂函数,动态创建AA,BB和CC,这样我就可以做到:

  AA = create_custom_subclass(A)
  a = AA()
  a.set_value()

2 个答案:

答案 0 :(得分:1)

Python中的类是first-class citizens,即您可以像对待任何其他对象一样对待它们。例如,您可以做一个简单的工厂:

def create_custom_subclass(cls):
    class sub(cls):
        def set_value(self):
            more_set_value()
            super().set_value()
    return sub

AA = create_custom_subclass(A)
a = AA()
a.set_value()

或者你可以做一个mixin(比工厂使用更少的内存):

class Mixin:
    def set_value(self):
        more_set_value()
        super().set_value()

class AA(Mixin, A):
    pass

答案 1 :(得分:0)

我不清楚你想做什么,但我会尽量给你一些指示。

Unlinke C ++,Python使用dynamic type system,即可以为变量分配任何类型的对象。这为您提供了各种可能性。

class CustomClass(object):
    def __init__(self, obj_of_t_class):
        self.obj_of_t_class = obj_of_t_class

    def set_value(self, value):
        self.obj_of_t_class.some_method(value)
        # do something else here

只要obj_of_t_class包含您尝试调用的方法,Python就不关心它是AB还是Z类型。

这应该大致相当于你想要用C ++模板类做的事情。