当一个特定的字符串呈现给父类的构造函数Python的方式分配一个子类变量的实例

Ben*_*Ben 5 python subclass variable-assignment

我希望能够创建父类X的实例,并使用字符串"Q"作为额外参数.
此字符串将是一个名称是用于父类X的一个子类Q上的标识符
我希望父类的实例,成为(或代替)的子类的实例.

我知道这可能是一个经典问题(错误?).经过一番搜索后,我找不到合适的解决方案.
我自己想出了以下解决方案;
我添加了一个可能的标识符字典作为其基类实例的键到父类的init -method.
然后将相应子类的 -attribute 分配给当前实例 -attribute.
我要求init -method 的参数不是默认值来防止无限循环.
以下是代码在实践中的样子示例;

class SpecialRule:
    """"""
    name="Special Rule"
    description="This is a Special Rule."
    def __init__(self, name=None):
        """"""
        print "SpecialInit"
        if name!=None:
            SPECIAL_RULES={
                "Fly" : FlyRule(),
                "Skirmish" : SkirmishRule()
                } #dictionary coupling names to SpecialRuleclasses
            self.__class__= SPECIAL_RULES[name].__class__

    def __str__(self):
        """"""
        return self.name

class FlyRule(SpecialRule):
    """"""
    name="Fly"
    description="Flies."
    def __init__(self):
        """"""
        print "FlyInit"+self.name
        SpecialRule.__init__(self)
    def addtocontainer(self, container):
        """this instance messes with the attributes of its containing class when added to some sort of list"""

class SkirmishRule(SpecialRule):
    """"""
    name="Skirmish"
    description="Skirmishes."
    def __init__(self):
        """"""
        SpecialRule.__init__(self)
    def addtocontainer(self, container):
        """this instance messes with the attributes of its containing class when added to some sort of list"""

test=SpecialRule("Fly")
print "evaluating resulting class"
print test.description
print test.__class__
</pre></code>
Run Code Online (Sandbox Code Playgroud)

输出:

> SpecialInit FlyInitFly SpecialInit evaluating resulting class Flies. main.FlyRule >

是否有更多的pythonic解决方案,并且有可预见的问题吗?(而且我错误地认为它是一个很好的编程实践来显式调用.__init__(self)子类中的父类.__init__?).我的解决方案感觉有点......错了......

快速回顾到目前为止;
谢谢你的快速解答

@Mark Tolonen的解决方案
我一直在研究__new__-method,但是当我尝试在Mark Tolonen的Z的示例子类中创建A,B和C时,我得到了Z类尚未定义的错误.此外,我不确定是否可以以正常方式(在Z的范围之外使用变量= A())实例化A类,除非您已经创建了子类的实例并将该类作为实例的属性调用Z的子类...这似乎不是很直接.__new__非常有趣,所以我会愚弄它,你的例子比我从pythondocs得到的更容易掌握.

@Greg Hewgill的解决方案
我尝试了静态方法解决方案,似乎工作正常.我之前考虑使用单独的函数作为工厂,但我猜想在主块中使用松散的构造函数代码列表管理大型程序会变得很困难,所以我很乐意将它集成到类中.
我做了一些实验,看看我是否可以将创建方法变成装饰.__call__()但它变得非常混乱所以我会留下它.

Gre*_*ill 3

我将通过使用封装对象选择的函数来解决这个问题:

class SpecialRule:
    """"""
    name="Special Rule"
    description="This is a Special Rule."
    @staticmethod
    def create(name=None):
        """"""
        print "SpecialCreate"
        if name!=None:
            SPECIAL_RULES={
                "Fly" : FlyRule,
                "Skirmish" : SkirmishRule
                } #dictionary coupling names to SpecialRuleclasses
            return SPECIAL_RULES[name]()
        else:
            return SpecialRule()
Run Code Online (Sandbox Code Playgroud)

我使用了装饰器来允许您在没有对象实例的情况下@staticmethod调用该方法。create()你可以这样称呼它:

SpecialRule.create("Fly")
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一下,这被称为工厂模式。 (4认同)