当特定字符串呈现给父类的构造函数时,将子类的实例分配给变量的Pythonic方法

当特定字符串呈现给父类的构造函数时,将子类的实例分配给变量的Pythonic方法,python,subclass,variable-assignment,Python,Subclass,Variable Assignment,我希望能够创建父类X的实例,并使用字符串“Q”作为额外参数。 该字符串是父类X的子类Q的标识符。 我希望父类的实例成为(或被替换为)子类的实例 我知道这可能是一个典型的问题(错误?)。经过一番搜索,我还没有找到合适的解决方案。 我自己提出了以下解决方案 我在父类的init-方法中添加了一个可能标识符的字典,作为其基类实例的键。 然后将相应子类的class-属性分配给当前实例class-属性。 我要求init-方法的参数不是默认值,以防止无限循环。 下面是代码在实践中的示例 class Speci

我希望能够创建父类X的实例,并使用字符串“Q”作为额外参数。
该字符串是父类X的子类Q的标识符。
我希望父类的实例成为(或被替换为)子类的实例

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

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>
类特殊规则:
""""""
name=“特殊规则”
description=“这是一条特殊规则。”
def uuu init uuuu(self,name=None):
""""""
打印“SpecialInit”
如果你的名字=无:
特别规则={
“Fly”:FlyRule(),
“小冲突”:小冲突()
}#字典将名称耦合到SpecialRuleClass
self.\uuuuu类\uuuuu=特殊规则[名称]。\uuuuu类__
定义(自我):
""""""
返回self.name
类飞行规则(特殊规则):
""""""
name=“Fly”
description=“苍蝇。”
定义初始化(自):
""""""
打印“FlyInit”+self.name
特殊规则。\uuuu初始\uuuuuu(自身)
def addtocontainer(自身,容器):
“”“将此实例添加到某种列表时,会弄乱其包含类的属性”“”
班级小冲突(特殊规则):
""""""
name=“小冲突”
description=“小冲突。”
定义初始化(自):
""""""
特殊规则。\uuuu初始\uuuuuu(自身)
def addtocontainer(自身,容器):
“”“将此实例添加到某种列表时,会弄乱其包含类的属性”“”
测试=特殊规则(“飞行”)
打印“评估结果类”
打印测试说明
打印测试__
输出:

> 特产 飞虱 特产 评估结果类 苍蝇。 main.FlyRule >

是否有一个更具python风格的解决方案,我的解决方案是否存在可预见的问题? (我是否错了,在子类的
。\uuuuu init\uuu
中显式调用父类的
。\uuuuuu init\uuuuu(self)
,这是一种很好的编程实践?)。 我的解决方案感觉有点。。。错了

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

@马克·托洛宁的解决方案
我一直在研究
\uuuuu new\uuuu-方法
,但当我试图在Mark Tolonen的示例子类Z中创建A、B和C时,我得到了一个错误,即类Z尚未定义。另外,我不确定是否可以用普通的方式实例化类A(变量=A()在Z的作用域之外),除非您已经创建了一个子类的实例,并将该类作为Z的子类实例的属性调用。。。这似乎不是很简单<代码>\uuuu new\uuuuu非常有趣,所以我将进一步讨论它,您的示例比我从pythondocs中得到的更容易理解

@格雷格·休吉尔的解决方案
我尝试了静态方法的解决方案,似乎效果很好。我以前考虑过使用单独的函数作为工厂,但我猜如果在主块中有一系列松散的构造函数代码,那么管理一个大型程序会变得很困难,因此我很高兴将其集成到类中。

我做了一些实验,看看是否可以将create方法转换为修饰的
。\uuuu call\uuuuu()
,但它变得非常混乱,所以我就不谈了。

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

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()
我使用了
@staticmethod
装饰器,允许您调用
create()
方法,而不必拥有对象的实例。你可以这样称呼它:

SpecialRule.create("Fly")

查找\uuuu新方法。这是覆盖类创建和初始化方式的正确方法

这里有一个快速破解:

class Z(object):
    class A(object):
        def name(self):
            return "I'm A!"
    class B(object):
        def name(self):
            return "I'm B!"
    class C(object):
        def name(self):
            return "I'm C!"

    D = {'A':A,'B':B,'C':C}

    def __new__(cls,t):
        return cls.D[t]()

顺便说一句,这就是所谓的工厂模式。请注意(正如Ben在其编辑中“注释”)对于
A、B、C
来说,要成为
Z
的子类,它们必须在
Z
的声明之外声明。由于有了新的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,他们可能会有自己的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
class Z(object):
    class A(object):
        def name(self):
            return "I'm A!"
    class B(object):
        def name(self):
            return "I'm B!"
    class C(object):
        def name(self):
            return "I'm C!"

    D = {'A':A,'B':B,'C':C}

    def __new__(cls,t):
        return cls.D[t]()