使用变量作为类名实例化一个类

3

我对Python有些陌生,希望有人能够帮我解决一个问题。

我需要使用列表中的变量来实例化多个对象。比如说,我有一个包含2个元素的列表 ["apple", "orange"] ,我想要以这些元素作为基于Fruit类的实例化类的名称,从而得到2个对象,即apple和orange,它们都是Fruit类的实例。

我尝试过这样做,但似乎无法将变量名用作实例化类的名称。下面这段代码并不起作用,但可能能帮助你理解我想要实现的内容:

class Fruit:
    pass

my_list = ["apple", "orange"]

for item in my_list:
    item = Fruit()

type(apple)

这个不起作用,但我希望这能让你了解我试图实现什么。我得到了这个错误:
NameError: name 'apple' is not defined

我希望看到的是:

>>> type(apple)
<type 'instance'>

任何人能提供的指导都将不胜感激 :) 谢谢!

4
不要在变量名中包含数据。使用字典代替(fruits = {},然后 fruits[item] = Fruit())。 - Martijn Pieters
+10 给Martijn的评论。这是大多数人(包括我在内)必须摆脱头脑中的最持久的想法之一,以改善我们的代码。 - ojdo
2个回答

3
动态创建变量通常不是一个好主意。最好使用字典代替:
>>> fruits = {}
>>> for item in my_list:
...    fruits[item] = Fruit()
... 

>>> [(k, type(v)) for k, v in fruits.items()]
[('orange', <class '__main__.Fruit'>), ('apple', <class '__main__.Fruit'>)]

我认为你可以通过操纵 globals() 在全局范围内做类似的事情,但我认为这是非常不好的做法。


@OllieSheridan 很高兴能够提供帮助,不客气。 - anon582847382

1
非常简单,首先将您的基础定义为新式类:
class Fruit(object):
    pass

然后动态地创建任何你想要的子类:
Apple = type("Apple", (Fruit, ), dict())

然后实例化它:
anapple = Apple()

type(anapple)
__main__.Apple

因此,您有苹果、橙子等各种水果。
如果您不需要共同的祖先,则可以从对象(object)派生出您的新类:
Apple = type("Apple", (object, ), dict())

最后,如果你已经定义了这些类,无论是动态还是静态的方式,你可以像这样查找它们,第一部分,同一模块:

class Apple: pass
class Orange: pass

for name in ["Orange", "Apple"]:
    instance = globals()[name]()

这里,globals是一个函数,因此首先使用()调用它,它返回一个字典,然后你在这个字典中查找你的水果,因此使用[],然后你得到一个类,并使用()实例化它。
最后,如果所有的水果都在某个模块中定义,例如:
# fruits.py
class Apple: pass
class Orange: pass

# user code
import fruits
anapple = getattr(fruits, "Apple")()

1
我认为OP在这里并不是在问子类化的问题。 - Ashwini Chaudhary
@Aशwiniचhaudhary 我想知道,也许我应该加入匿名类... - Dima Tisnek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接