我想在实例化时选择一个子类,以从某些类中选择特定的属性。我已经解决了以下问题:
代码
class Foo:
a = "foo"
def __init__(self, dtype=Bar):
self.__class__ = dtype
class Bar:
b = "bar"
class Baz(Bar):
c = "baz"
Demo
Foo(dtype=Bar).b
# 'bar'
Foo(dtype=Baz).b
# 'bar'
Foo(dtype=Baz).c
# 'baz'
这将提供所需的结果,从Bar
中选择特定的属性,同时可选地使用Baz
扩展特征。但是,与子类化不同,我们无法访问Foo
的属性。
Foo(dtype=Baz).a
# AttributeError: 'Baz' object has no attribute 'a'
在某些情况下,并非所有属性都需要,因此不优选将子类Foo(Baz)
用作子类。
在Python中完成此操作的惯用类比是什么?
如果您确实想要Foo
或Bar
的实例,为什么要首先创建Baz
的实例?而是将Foo
设为Bar
和Baz
实例的工厂。
class Bar:
b = "bar"
class Baz(Bar):
c = "baz"
class Foo:
a = "foo"
def __new__(cls, dtype=Bar):
return dtype()
如果您只是Foo
的继承,怎么办?
class Foo:
a = "foo"
def __init__(self, dtype='Bar'):
if dtype == Bar:
self.__class__ = Bar
elif dtype == Baz:
self.__class__ = Baz
class Bar(Foo):
b = "bar"
class Baz(Foo):
c = "baz"
print(Foo(dtype=Bar).b) # bar
print(Foo(dtype=Baz).c) # baz
print(Foo(dtype=Baz).a) # foo
还请注意,运行您的代码段将导致
NameError: name 'Bar' is not defined
因此,当为Forward Reference使用默认值时,应使用dtype
。
直接将dtype
分配给self.__class__
,即也可以得到相同的结果>
def __init__(self, dtype='Bar'):
self.__class__ = dtype
正如我在评论中提到的,仅使用纯继承。