简体   繁体   English

如何在python中以优雅的方式动态创建对象?

[英]How to create objects dynamically in an elegant way in python?

I have two classes that I would like to merge into a composite. 我有两个类,我想合并到一个复合。 These two classes will continue to be used standalone and I don't want to modify them. 这两个类将继续独立使用,我不想修改它们。 For some reasons, I want to let my composite class creating the objects. 出于某些原因,我想让我的复合类创建对象。 I am thinking about something like the code below (it is just an example) but I think it is complex and I don't like it very much. 我正在考虑类似下面的代码(这只是一个例子),但我认为它很复杂,我不太喜欢它。 I guess that it could be improved by some techniques and tricks that I ignore. 我想这可以通过我忽略的一些技巧和技巧来改进。

Please note that the composite is designed to manage a lot of different classes with different constructor signatures. 请注意,复合材料旨在管理具有不同构造函数签名的许多不同类。

What would recommend in order to improve this code? 为了改进此代码,会建议什么?

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()

You could shorten it by removing type-checking _make_object , and letting class constructors take care of the default arguments, eg 您可以通过删除类型检查_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()

This would also allow you to use it with new classes without modifying its code. 这也允许您在不修改代码的情况下将它与新类一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM