2013-02-12 3 views
0

Скажем, у меня есть этот код:Вызов конструктора без назначения; инстанцирует позже

models.py:

class Square: 
    def __init__(self, name, value): 
    self._name = name 
    self._value = value 

mymodule.py:

from models import Square 
Square('hello', 'there') 

main.py

m = __import__('mymodule') 
for i in dir(m): 
    if i == 'Square': 
    models.append(getattr(m, i)) 

Мой вопрос заключается в : как мне создать экземпляр Square I (с аргументами, которые я дал в mymodule.py, из курс)?

Идея заключается в создании экземпляра площади позже.

Спасибо!

+0

Откуда взялись 'models' в main.py? – martineau

+0

@martineau Просто список python. – user1491915

+0

ОК, это было путано из-за 'из моделей ...' у вас в mymodule.py и не было определения для него нигде в вашем main.py. – martineau

ответ

2

У вас есть недостаток в файле mymodule.py; вы никогда магазин экземпляра. Храните его в переменной:

somevariable = Square('hello', 'there') 

Вы не можете просто вызвать конструктор и позволить ему болтаться.

Зацикливание по атрибутам mymodule в поисках чего-то с именем Square не получит то, что вы хотите, вы найдете ссылку на класс, а не экземпляр.

Может быть, вы должны искать объекты Square типа вместо:

from models import Square 

for value in vars(m).itervalues(): 
    if isinstance(value, Square): 
     models.append(value) 

Если вы хотите, чтобы избежать необходимости импортировать Square класс, вы должны проверить имя типа вместо, который более хрупкими:

for value in vars(m).itervalues(): 
    if getattr(type(value), '__name__', None) == 'Square': 
     models.append(value) 

Если вы действительно хотите отложить строительство, вместо того, чтобы построить его позже с набором предварительно заданных значений, используйте functools.partial():

from models import Square 
from functools import partial 

somevariable = partial(Square, 'hello', 'there') 

Если теперь импортировать somevariable и вызов его, парциальное будет применять аргументы уже переданные в и создать экземпляр:

instance = somevariable() # calls Square('hello', 'there') 
+0

Не так ли просто ссылку на класс? Мне было бы интересно создать его с аргументами, которые я дал изначально. – user1491915

+0

Откуда берутся имя и ценность? Я хочу использовать «hello» и «there», которые я передал в mymodule.py (этот конкретный вызов). – user1491915

+0

Извините, я неправильно понял ваш вопрос; перечитывание приводило к * другому * ответу. –

0

На самом деле вы являются инстанцировании его в mymodule.py, но он отбрасывается. Чтобы остановить это, вам нужно сохранить Square, созданный там в чем-то с именем, иначе он будет собран из мусора, поскольку на него ничего не ссылается. Вот что я имею в виду:

mymodule.py:

from models import Square 
a_square = Square('hello', 'there') # name it 

Затем вы можете получить доступ к нему напрямую и более быстро, используя это имя в main.py так:

основной.ру

models = [] 
mod = __import__('mymodule') 
models.append(vars(mod)['a_square']) # access it by name 
0

«Идея состоит в том, чтобы создать экземпляр площадь позже.»

Вы можете сделать это, сохранив вызываемые и аргументы.

import models 
# save as (callable, args, keywords). This does not create a Square 
my_model = (model.Squares, ('hello', 'there'), {}) 
# sometime later, create the square 
my_square = my_model[0](*my_model[1], **my_model[2]) 

Или, если вы хотите, чтобы получить супер фантазии и создать много моделей, вы можете составить список:

models.py:

class Square(object): 
    def __init__(self, name, value): 
    self._name = name 
    self._value = value 

class Round(object): 
    def __init__(self, name, value, otherstuff=None): 
    self._name = name 
    self._value = value 
    self._otherstuff = otherstuff 

mymodule.py:

import models 
my_models = (
    (models.Square, ('hello', 'there'), {}), 
    (models.Round, ('goodbye', 'there'), {'otherstuff':'stuff'}) 
) 

main.py

m = __import__('mymodule') 
models = [model[0](*model[1], **model[2]) for model in m.my_models] 
Смежные вопросы