在Python中动态访问类实例的“name”

3 投票
3 回答
1741 浏览
提问于 2025-04-15 22:08

简单来说:我在一个循环里动态创建类的实例,然后这个类会为每个实例定义一些属性。之后我需要在另一个循环中查找这些属性的值。

示例代码:

class A:
    def __init__(self, name, attr):
        self.name=name
        self.attr=attr

names=("a1", "a2", "a3")
x=10
for name in names:
    name=A(name, x)
    x += 1
...
...
...
for name in names:
    print name.attr

我该如何为这些实例创建一个标识符,以便以后可以通过“名字”来访问它们呢?

我找到了一种方法,通过将“名字”和内存位置关联起来来实现:

class A:
    instances=[]
    names=[]
    def __init__(self, name, attr):
        self.name=name
        self.attr=attr
        A.instances.append(self)
        A.names.append(name)

names=("a1", "a2", "a3")
x=10
for name in names:
    name=A(name, x)
    x += 1
...
...
...
for name in names:
    index=A.names.index(name)
    print "name:  " + name
    print "att:  " + str(A.instances[index].att)

这让我在网上搜索了两天,但一直没有找到答案。也许是我不知道怎么问这个问题,或者可能根本就做不到(很多其他帖子似乎都在暗示这一点)。

现在这个第二个例子是有效的,暂时我会用这个方法。我只是觉得应该有比自己创建一个临时字典来存储索引号更简单的方法,我希望我没有浪费两天时间去寻找一个不存在的答案。有没有人有什么建议?

提前谢谢你们,
安迪

更新:一位同事刚刚告诉我他认为最简单的方法,就是用实例的“名字”作为键,创建一个实际的类实例字典。

3 个回答

1

是的,使用字典的方法应该很好用,而且可以直接融入到类里面。

class A:
    _instances = {}

    @classmethod
    def get(cls, name):
        return A._instances[name]

    def __init__(self, name, attr):
        self.name=name
        self.attr=attr
        A._instances[name] = self

a = A('foo', 10)
aa = A.get('foo')

如果你想尝试一下 __new__,你甚至可以让这个过程变得更简单透明:

a = A('foo', 10)
aa = A('foo') # 'a' and 'aa' refer to the same instance.

这个有点复杂,所以我就不多说了,你可以自己去查资料(当然,如果遇到问题也可以在StackOverflow上问其他问题)。

2

其实没必要把实例字典放在类里面。只需要在本地范围内创建一个字典,叫做 inst

class A:
    def __init__(self, name, attr):
        self.name=name
        self.attr=attr

inst={}
names=("a1", "a2", "a3")
x=10
for name in names:
    inst[name]=A(name, x)
    x += 1

然后,每当你想通过名字访问某个实例时,只需使用 inst[name]

for name in names:
    print inst[name].attr
4

有时候,简单就是最好的选择。用一个字典来存储你的实例,把它们的名字当作键,这样做既简单又容易实现。

class A:
    instances={}
    def __init__(self, name, attr):
        self.name=name
        self.attr=attr
        A.instances[name] = self

然后要获取正确的实例,只需要...

instance = A.instances[name]

撰写回答