我的问题原则上很普遍。我有一个名为Menu
的类,其列表为items
,其中一个或多个项可以是字符串,也可以是Menu
的另一个实例。我的代码如下:
class Menu():
def __init__(self):
self.items = []
def add_item(self, item):
self.items.append(item)
def add_menu(self):
self.add_item(Menu())
正如您所看到的,我在其中一个函数中使用了类Menu
的实际名称。我的问题是,如果可以在不编写类的实际名称的情况下这样做,而是通过引用它定义的类来实现吗?例如,我试过
self.add_item(super(self))
提供TypeError: super() argument 1 must be type, not Menu
并尝试了
self.add_item(super())
运行没有错误,但它插入的对象是<super: <class 'Menu'>, <Menu object>>
我开始怀疑我正在使用错误的工具来完成工作,我的问题是我做错了什么?并且正在引用我可能需要的类型吗?
如果相关我的python版本是3.5.3
答案 0 :(得分:2)
当然有可能:
>>> class A:
... def create_instance(self):
... return type(self)()
...
>>> a1 = A()
>>> a2 = a1.add_self()
>>> a1
<__main__.A object at 0x1029c27f0>
>>> a2
<__main__.A object at 0x1029c28d0>
注意,当然,这是因为:
>>> type(a1)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(a1) is A
True
或者,这也可能是classmethod
的用例:
>>> class A:
... @classmethod
... def make_instance(cls):
... return cls()
...
>>> a1 = A()
>>> a2 = a1.make_instance()
>>> a1
<__main__.A object at 0x1029c29b0>
>>> a2
<__main__.A object at 0x1029c27f0>
现在,一个类的实例返回同一个类的新实例是完全合理的,但是在你的情况下是否可取,我认为我没有足够的信息来发表意见。但它肯定是可能的。
答案 1 :(得分:0)
错误的抽象:考虑创建一个类 MenuItem - 例如 - 表示单行菜单条目或子菜单。或者一些你今天想不到的其他类型的菜单条目。
换句话说:好的OOP是关于创建有用的抽象。菜单项可以有许多不同的形状,因此更好的答案是不适合原始字符串,而是想出一个支持您解决问题的继承层次结构。