如何取回类的动态创建的对象?

Posted

技术标签:

【中文标题】如何取回类的动态创建的对象?【英文标题】:How can I get back the dynamically created objects of a class? 【发布时间】:2012-12-21 19:56:44 【问题描述】:

我有 一个字符串列表 my_list,其中包含 n 个项目。 此列表在运行时逐个输入字符串。 假设现在有 4 个项目。

示例:my_list = ['one', 'two', 'three', 'four']

我有一个自定义对象,名为my_object,我需要使用循环创建其中的实例,为列表中的每个项目

我的问题: 通常,我将对象创建为:**my_obj** = MyObj(),我可以使用 my_obj 变量来获取它并调用它的方法等。

因为我需要通过列表操作动态地进行创建;

如何创建对象实例? 如何获取对象实例并调用其方法?

我知道它很旧,可能是错误的和过时的,但在 VisualBasic 中,对于视觉项目,这可能是这样执行的:

my_obj[动态变量] = ...

我不希望这涉及到全局变量或任何东西。

我该如何处理这个问题?

更多背景:

*我正在使用 Qt (PySide - PyQt) 开发应用程序。 我有一个定制的小部件(my_class) 我需要用这个对象的动态创建的实例填充一个可视列表(QGridLayout),然后调用它们的方法。*

谢谢。

显示我正在创建对象并尝试使用它们的代码:

class my_class(object):
    def __init__(self):
        print 'hi'
    def talk(w):
        print w

my_list = ['one', 'two']

### code that won't work starts from here 
for i in list:
    i = my_class()

my_list[1].talk() 

【问题讨论】:

请展示实际代码,说明您正在尝试做什么以及它不工作的原因。 代码到底是什么?我很想这样做,但这就是我要问的。我有一个随机的自定义类,它还没有做任何事情。我的问题是如何创建动态实例,我不知道它的代码。 你通过调用一个类来创建一个对象,例如MyClass()。无需将其分配给变量。您的“问题”听起来很愚蠢,以至于我认为我们缺少上下文。显示代码。 @Phil:显示您创建对象并尝试使用它们的代码。 所有类和对象都是动态创建的(即在运行时)。没有“非动态”的方式来做到这一点。要在以后检索它,只需确保它以某种方式在范围内(通过变量、属性、集合等)并获取它。 【参考方案1】:

你只是说你想创建一个没有名字的对象列表吗?只需执行以下操作:

myObjs = [MyObj() for i in range(5)]

然后你就可以用myObjs[0]myObjs[1]等来访问每个对象了

另外,请阅读the Python tutorial 以熟悉在 Python 中创建类实例、列表等的基础知识。

编辑:您在评论中描述的内容(创建具有给定名称的变量)不是一个好主意。创建一个动态变量名是没有意义的,因为你不能在不知道变量名是什么的情况下在代码中使用它。最好使用列表或字典。对于 dict,您可以执行以下操作:

myObjs = 
theName = getNameSomehowFromUser()
myObjs[theName] = MyObj()

然后随心所欲地执行此操作,将新对象添加到名为 myObjs 的字典中。

【讨论】:

@BrenBam,感谢您的友好回答。我理解你建议的方式。所以基本上你是在建议我应该创建一个新的对象列表并使用列表索引来检索它们?我明白了,谢谢,我会应用它。但是我必须告诉你,我确实阅读了很多关于 Python 和文档的内容,并且也完成了课程。我只是认为会有一种内置的方法来动态命名实例并在以后访问它们,就像在古代 VisualBasic 中一样。 @Phil 你是说字典吗?这就是你想要的吗? @Marcin,想象一个应用程序在运行时从用户那里接收一个字符串。我希望 Python 创建一个类的实例并将接收到的字符串作为变量名,然后稍后使用该字符串检索创建的实例。 @Phil:这不是一个好主意。而是使用列表或字典来保存您的对象。请参阅我编辑的答案。 @Phil 按照 BrenBarn 的建议去做。如果您觉得任何解决了您的问题,如果您接受答案也很好。【参考方案2】:

我想你可能对 Python 中“变量”和“名称”的含义感到困惑。

对象没有名称。说 foo = 1 不会对 1 对象做任何事情,除了增加它的引用计数。

变量是字符串到命名空间内对象的映射。命名空间是用 dicts 实现的。您可以使用locals() 函数访问本地命名空间。

例子:

Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> locals()
'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None
>>> a = 1
>>> locals()
'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'a': 1, '__package__': None
>>> 

注意 'a':1 出现在 locals() 字典中。

您的问题仍然不清楚,因为您没有显示任何代码与您想要完成的任务以及您卡在哪里。做我认为你想做的事情的最好方法可能是使用字典:

>>> class MyClass(object): pass
... 
>>> myobjects = 
>>> myobjects['key-name'] = MyClass()
>>> myvar = myobjects['key-name']  # some time later...
>>> myvar # what is myvar?
<__main__.MyClass object at 0x10f7c1c50>
>>> myobjects['key-name'] # myobjects['key-name'] is the same object
<__main__.MyClass object at 0x10f7c1c50>
>>> 

【讨论】:

【参考方案3】:

我是如何解决这个问题的:

我决定使用一个名为“instances”的类属性,将所有新创建的实例附加到该属性中。这可以是字典或列表。然后可以使用字符串或索引 int 来检索它们。

太棒了。

【讨论】:

以上是关于如何取回类的动态创建的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何以多态方式创建对象的动态数组?

动态创建对象 C++

如何复制动态分配的对象(具有一个类的 const 成员)

如何在 Restkit 中执行没有正文、url 参数的 PUT 请求并取回对象

如何从基类动态创建和使用派生类?

创建抽象类的动态数组