在Python中实例化时选择一个子类

问题描述 投票:0回答:3

我想在实例化时选择一个子类,以从某些类中选择特定的属性。我已经解决了以下问题:

代码

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中完成此操作的惯用类比是什么?

python subclass
3个回答
1
投票

如果您确实想要FooBar的实例,为什么要首先创建Baz的实例?而是将Foo设为BarBaz实例的工厂。

class Bar:
    b = "bar"

class Baz(Bar):
    c = "baz"

class Foo:
    a = "foo"

    def __new__(cls, dtype=Bar):
        return dtype()

0
投票

如果您只是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

0
投票

正如我在评论中提到的,仅使用纯继承。

© www.soinside.com 2019 - 2024. All rights reserved.