在Python中实例化时选择子类

在Python中实例化时选择子类,python,subclass,Python,Subclass,我想在实例化时选择一个子类,从某些类中选择特定的属性。我得出了以下结论: 代码 演示 这将提供所需的结果,从工具栏中选择特定属性,同时可以选择使用Baz扩展功能。然而,与子类化不同,我们无法访问Foo的属性 Foo(dtype=Baz).a # AttributeError: 'Baz' object has no attribute 'a' 有时并非所有属性都是必需的,因此子类化FooBaz不是首选 在Python中实现这一点的惯用类比是什么?如果你真的想要一个Bar或Baz的实例,为什么要

我想在实例化时选择一个子类,从某些类中选择特定的属性。我得出了以下结论:

代码

演示

这将提供所需的结果,从工具栏中选择特定属性,同时可以选择使用Baz扩展功能。然而,与子类化不同,我们无法访问Foo的属性

Foo(dtype=Baz).a
# AttributeError: 'Baz' object has no attribute 'a'
有时并非所有属性都是必需的,因此子类化FooBaz不是首选

在Python中实现这一点的惯用类比是什么?

如果你真的想要一个Bar或Baz的实例,为什么要首先创建一个Foo实例?相反,让Foo成为Bar和Baz的工厂


正如我在评论中提到的,只需使用普通继承

class Foo:
    a = "foo"

class Bar(Foo):
    b = "bar"

class Baz(Foo):
    c = "baz"

# Example use
import random
class_to_instantiate = Bar if random.choice([True, False]) else Baz
print(class_to_instantiate().a)
输出

foo

为什么不能直接使用继承呢?您可以动态地选择子类,比如var=Bar;这听起来像是一个错误。我不知道这样做会是惯用的。@KentShikama选择var=Bar仍然排除Foo.Per中的属性,如果uu new uu返回一个包含子类的实例,将调用u init u。但这都是按类型执行的;还可以看到,返回不同类型的新类型应该是非常罕见的;我只在FFI相关代码中将NULL映射为None。
class Bar:
    b = "bar"

class Baz(Bar):
    c = "baz"

class Foo:
    a = "foo"

    def __new__(cls, dtype=Bar):
        return dtype()
class Foo:
    a = "foo"

class Bar(Foo):
    b = "bar"

class Baz(Foo):
    c = "baz"

# Example use
import random
class_to_instantiate = Bar if random.choice([True, False]) else Baz
print(class_to_instantiate().a)
foo