【发布时间】:2013-09-24 00:53:12
【问题描述】:
我想从"red apple" 等字符串构造类。这将创建Apple 类的实例,它是Fruit 的子类。问题是,color 属性应该属于Fruit,而不是Apple。因此,在我看来,创建对象的自然方式是:
- 解析字符串
- 创建
Fruit(color="red") - 创建
Apple() - 以某种方式使其成为一个实体
到目前为止,我有 3 个选择:
-
一切都变成参数
class Fruit(object): def __init__(self, color): self.color = color def observe(self): print "Looks like a tasty %s fruit" % self.color @classmethod def fromstring(cls, string): color, kind = string.split() if kind == "apple": return Apple(color) class Apple(Fruit): def __init__(self, *args, **kwargs): super(Apple, self).__init__(*args, **kwargs) self.tasty = True def bite(self): print "I bite into a tasty apple" fruit = Fruit.fromstring("red apple") -
color属性是从外部填写的class Fruit(object): def observe(self): print "Looks like a tasty %s fruit" % self.color @classmethod def fromstring(cls, string): color, kind = string.split() if kind == "apple": ins = Apple() ins.color = color return ins class Apple(Fruit): def __init__(self): self.tasty = True def bite(self): print "I bite into a tasty apple" fruit = Fruit.fromstring("red apple") -
最直接的方法:替换
__class__class Fruit(object): def __init__(self, string): self.color, kind = string.split() if kind == "apple": self.__class__ = Apple Apple.__init__(self) def observe(self): print "Looks like a tasty %s fruit" % self.color class Apple(Fruit): def __init__(self): self.tasty = True def bite(self): print "I bite into a tasty apple" fruit = Fruit("red apple")
跑步
fruit.observe()
fruit.bite()
print type(fruit), fruit.tasty
给出相同的输出:
Looks like a tasty red fruit
I bite into a tasty apple
<class '__main__.Apple'> True
第一种方法可以说是最通用的方法,它需要传递诸如color 之类的参数,在第三种方法中处理得更加优雅。然而,改变__class__ 听起来像是使用高级工具来完成一项平凡的任务。有没有更好的方法来实现目标,或者我最好使用其中一种方法?
更新:我可能必须指出,在现实生活中Fruit 和Apple 的初始化程序应该设置的属性数量是变量,大约共 15 个。
【问题讨论】:
-
水果是否应该提供构造函数?也许基类应该只是一个bass类,并且应该有某种工厂来实例化正确种类的水果,那么Fruits根本不需要知道子类
-
我只是认为调用 Fruit.fromstring() 会是制作水果的好方法。不,Fruit 不需要注意孩子。
-
“我可能必须指出,在现实生活中
Fruit和Apple的初始化程序应该设置的属性数量是可变的,总共大约15 个。” - 这是一个主要的代码气味。为什么在初始化时设置 15 属性?您能否进一步扩展您的问题,使其更接近“现实生活”? -
我相信你正在寻找一个类似于
fromstring的工厂函数,只是你不会拥有它作为Fruit的成员
标签: python class inheritance