2010-04-28 5 views
1

Простым английским: я динамически создаю экземпляры классов в цикле for, тогда класс определяет несколько атрибутов для экземпляра. Мне нужно позже, чтобы найти эти значения в другом цикле.Динамическое расширение экземпляра класса экземпляра класса «имя» в Python

Пример кода:

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) 

Это был я рыщут в Интернете в течение 2 дней, и я не смог найти ответ. Может быть, я не знаю, как правильно задать вопрос, или, может быть, это невозможно сделать (как и многие другие сообщения, казалось, предлагали).

Теперь этот второй пример работает, и пока я его буду использовать. Я просто думаю, что должен быть более простой способ, чем создавать свой собственный импровизированный словарь индексов, и я надеюсь, что не потратил 2 дня на поиск ответа, которого нет. У кого-нибудь есть что-нибудь?

Спасибо заранее, Энди

Update: Коллега только что показал мне, что он думает, что это самый простой способ, и это сделать реальный словарь экземпляров класса с использованием «имя» экземпляра в качестве ключа.

ответ

3

Иногда держать его просто лучше. Имея dict, который хранит ваши экземпляры с их именами, поскольку ключи были бы простыми и довольно простыми для реализации.

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

, а затем, чтобы получить правильный экземпляр, просто ...

instance = A.instances[name] 
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. 

Это немного сложнее, так что я оставлю его вам исследовать (и, конечно, задайте еще один вопрос, если вы застряли).

2

Не нужно помещать экземпляр dict внутри класса. Просто создайте Dict, 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 
+0

Почему * не * положить Dict внутри класс? Это гораздо разумнее, чем организация, если она будет использоваться. – Amber

+0

Что произойдет, если OP имеет много классов с именованными экземплярами ('a1', 'a2', 'b1', 'b2')? Он действительно хочет получить к ним доступ с помощью 'A.instances ['a1']' и 'B.instances ['b1']'? Необходимость выбора правильного класса и правильного имени является ненужной и избыточной. Имена могут и должны быть уникальными. Поэтому они должны быть доступны из общего дикта, определенного вне любого класса. Как я вижу, вопрос, заданный ОП, заключается в том, как иметь дело с динамически названными * переменными * и не имеет ничего общего с тем фактом, что значения этих переменных являются экземплярами класса. – unutbu

+0

@ ~ unutbu, что все полностью зависит от проблемы. Возможно, что коды _wants_ A и B имена находятся в отдельных пространствах имен. И даже в случае совместного пространства имен, для всех таких типов было бы более унаследовано от некоторого общего типа NamedObject, который реализует все. Следует избегать инъекции материала во внешние пространства имен, где это практически возможно. –