4

我有一个基类,我想从中创建许多子类。子类的不同之处仅在于实例化期间用于调用基类的参数。下面的例子展示了如何创建一个子类Apple。有没有办法以编程方式执行此操作,而无需编写子类的__init__方法?这似乎是元类的工作,但在这种情况下,我无法修改基类。

apple = {'color': 'red', 'shape': 'sphere'}
pear = {'color': 'yellow', 'shape': 'cone'}
melon = {'color': 'green', 'shape': 'prolate'}

class Fruit(object):
    def __init__(self, color, shape):
        self.color = color
        self.shape = shape        

class Apple(Fruit):
    def __init__(self):
        Fruit.__init__(self, **apple)
4

3 回答 3

6

请参阅 type() 函数。

def make_fruit(name, kwargs):
    def my_init(self):
        Fruit.__init__(self, **kwargs)
    return type(name, (Fruit,), {'__init__': my_init})

Apple = make_fruit('Apple', apple)
于 2013-08-23T12:50:34.123 回答
3

使用类型

class Fruit(object):
    def __init__(self, color, shape):
        self.color = color
        self.shape = shape        

apple = {'color': 'red', 'shape': 'sphere'}
pear = {'color': 'yellow', 'shape': 'cone'}
melon = {'color': 'green', 'shape': 'prolate'}

g = globals()
for clsname, attrs in [('Apple', apple), ('Pear', pear), ('Melon', melon)]:
    def temp(attrs):
        g[clsname] = type(clsname, (Fruit,), {
            '__init__': lambda self: Fruit.__init__(self, **attrs)
        })
    temp(attrs)

>>> a = Apple()
>>> p = Pear()
>>> m = Melon()
>>> assert a.color == 'red' and a.shape == 'sphere'
>>> assert p.color == 'yellow' and p.shape == 'cone'
>>> assert m.color == 'green' and m.shape == 'prolate'
于 2013-08-23T12:49:18.633 回答
0

我认为您正在寻求的解决方案不存在:我所有的子类都共享相同的构造函数,那么唯一使该类独一无二的是它的名称。而且我认为您不希望有一个通用构造函数来检查类名以选择要做什么。

所以我认为:

  • 要么您在每个子类中重新定义构造函数,并精确将哪个参数传递给父构造函数,
  • 要么您将特定的常量值放在某个类成员中,然后构造函数使用它来调用父构造函数

在另一个线程中看到有趣的事情:Python 中的类工厂

于 2013-08-23T12:44:12.967 回答