为了账号安全,请及时绑定邮箱和手机立即绑定

如何从 python 中传递给超类的字符串创建子类?

如何从 python 中传递给超类的字符串创建子类?

小唯快跑啊 2022-10-18 17:03:33
给定一个具有两个(或许多)子类的超类,为简单起见,我们分别称它们为 Super、Sub1 和 Sub2。我想实例化 Sub1 和 Sub2 如下:s1 = Super('Sub1') s2 = Super('Sub2')即,将子类的名称作为字符串传递给超类的构造函数。想到的事情是在 Super 中使用子类的名称定义一个类变量,并在 Super 类的构造函数中使用几个 if 语句,可以调用相应的子类构造函数。我不完全确定这是否可行,但对我来说似乎很乱。欢迎任何关于如何用干净和 Pythonic 的方法解决这个问题的建议。
查看完整描述

2 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

这需要重写Super.__new__以使其成为工厂函数。


class Super:

    def __new__(cls, subclass_name, *args, **kwargs):

        for sc in cls.__subclasses__():

            if sc.__name__ == subclass_name:

                return super().__new__(sc, *args, **kwargs)

        raise ValueError("No such subclass")    



class Sub1(Super):

    pass



class Sub2(Super):

    pass



assert type(Super('Sub1')) is Sub1

这需要更多的工作来允许您直接定义一个子类(就像Sub1()调用一样Super.__new__,因为Sub1.__new__没有定义)。


因此,我更喜欢采用类名的专用类方法,而不是覆盖__new__.


class Super:

    @classmethod

    def subclass_by_name(cls, name, *args, **kwargs):

        for sc in cls.__subclasses__():

            if sc.__name__ == name:

                return sc(*args, **kwargs)

        raise ValueError("No such subclass")



assert type(Super.subclass_by_name('Sub1')) is Sub1


查看完整回答
反对 回复 2022-10-18
?
蛊毒传说

TA贡献1895条经验 获得超3个赞

我真的不认为这是一个好主意。超类并不意味着作为可能子类的有限列表的容器,这几乎完全违背了继承的观点。如果我是你,我会创建一个简单的工厂,从中可以构造我想要的对象,例如:


class Fruit():

  ...


class Apple(Fruit):

  ...


class Pear(Fruit):

  ...



fruits = {

   "apple": Apple,

   "pear": Pear       

}


def make_fruit(name, **kwargs):

    return fruits[name](**kwargs)


apple = make_fruit("apple", colour="red")

pear = make_fruit("pear", size="small)


查看完整回答
反对 回复 2022-10-18
  • 2 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信