【问题标题】:Instantiate a class using a variable for its name [duplicate]使用变量作为名称实例化一个类[重复]
【发布时间】:2014-05-25 12:38:33
【问题描述】:

我对 Python 有点陌生,希望有人能帮助我解决我遇到的问题。

我需要使用列表中的变量来实例化多个对象。假设我有一个包含 2 个项目的列表,["apple", "orange"] 我想使用这些作为基于类 Fruit 的实例化类的名称,所以我最终得到 2 个对象,apple 和 orange,它们是水果类的。

我试过这样做,但我似乎无法弄清楚如何使用变量名作为实例化类的名称。此代码不起作用,但可能会让您对我想要实现的目标有所了解:

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'>

任何人都可以提供的任何指针将不胜感激:)

谢谢!

【问题讨论】:

  • 不要。将数据保留在变量名之外。请改用字典(fruits = {},然后是fruits[item] = Fruit())。
  • +10 到 Martijn 的评论。这是大多数人(包括我)为了改进代码而不得不摆脱的最持久的想法之一。

标签: python variables for-loop instantiation


【解决方案1】:

真的很简单,首先让你的基类成为一个新样式的类:

class Fruit(object):
    pass

然后动态创建你想要的任何子类:

Apple = type("Apple", (Fruit, ), dict())

然后实例化它:

anapple = Apple()

type(anapple)
__main__.Apple

所以你有appleorange等,都是水果。

如果你不需要一个共同的祖先,你可以从object派生你的新类:

Apple = type("Apple", (object, ), dict())

最后,如果您已经动态或静态定义了这些类,您可以像这样查找它们,第 1 部分,相同模块:

class Apple: pass
class Orange: pass

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

这里,globals 是一个函数,因此首先(),它返回一个字典,然后你在这个字典中查找你的水果,因此[] 然后你得到一个类并用@987654332 实例化它@。

最后,如果你所有的水果都在某个模块中定义,例如:

# fruits.py
class Apple: pass
class Orange: pass

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

【讨论】:

  • 我不认为 OP 在这里询问子类化。
  • @Aशwiniचhaudhary 我想知道,也许我也应该添加匿名类...
【解决方案2】:

动态创建变量通常不是一个好主意。只需使用字典即可​​:

>>> 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 很高兴为您提供帮助,不客气。
猜你喜欢
  • 2021-03-17
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 2011-07-25
  • 2011-01-06
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
相关资源
最近更新 更多