如何优雅地在Python中动态创建对象?

3 投票
1 回答
1543 浏览
提问于 2025-04-15 14:01

我有两个类,想把它们合并成一个复合类。这两个类我还会单独使用,所以不想对它们进行修改。

出于某些原因,我希望我的复合类来创建这些对象。我在想下面的代码(这只是个例子),但我觉得它有点复杂,我不太喜欢。也许有一些我不知道的技巧可以让它更简单。

请注意,这个复合类是为了管理很多不同的类,而这些类的构造函数参数也各不相同。

你有什么建议可以改进这段代码吗?

class Parent:
    def __init__(self, x):
        self.x = x

class A(Parent):
    def __init__(self, x, a="a", b="b", c="c"):
        Parent.__init__(self, x)
        self.a, self.b, self.c = a, b, c

    def do(self):
        print self.x, self.a, self.b, self.c

class D(Parent):
    def __init__(self, x, d):
        Parent.__init__(self, x)
        self.d = d

    def do(self):
        print self.x, self.d

class Composite(Parent):
    def __init__(self, x, list_of_classes, list_of_args):
        Parent.__init__(self, x)
        self._objs = []
        for i in xrange(len(list_of_classes)):
            self._objs.append(self._make_object(list_of_classes[i], list_of_args[i]))

    def _make_object(self, the_class, the_args):
        if the_class is A:
            a = the_args[0] if len(the_args)>0 else "a"
            b = the_args[1] if len(the_args)>1 else "b"
            c = the_args[2] if len(the_args)>2 else "c"
            return the_class(self.x, a, b, c)
        if the_class is D:
            return the_class(self.x, the_args[0])

    def do(self):
        for o in self._objs: o.do()


compo = Composite("x", [A, D, A], [(), ("hello",), ("A", "B", "C")])
compo.do()

1 个回答

2

你可以通过去掉类型检查的 _make_object 来简化这个过程,让类的构造函数来处理默认参数,比如:

class Composite(Parent):
    def __init__(self, x, list_of_classes, list_of_args):
        Parent.__init__(self, x)
        self._objs = [
            the_class(self.x, *the_args)
            for the_class, the_args
            in zip(list_of_classes, list_of_args)
            if isinstance(the_class, Parent.__class__)
        ]

    def do(self):
        for o in self._objs: o.do()

这样做还可以让你在不修改代码的情况下,使用它来创建新的类。

撰写回答