调用没有赋值的构造函数;稍后实例化

时间:2013-02-12 22:26:26

标签: python class reflection instantiation

假设我有这段代码:

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中提供的参数)?

想法是稍后实例化广场。

谢谢!

3 个答案:

答案 0 :(得分:2)

您的mymodule.py文件存在漏洞;你从不存储实例。将其存储在变量中:

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

你不能只是调用构造函数让它摇晃。

循环查找名为mymodule的{​​{1}}的属性不会得到你想要的东西,你会找到类引用,而不是实例。

也许您应该寻找Square类型的对象:

Square

如果您想避免导入from models import Square for value in vars(m).itervalues(): if isinstance(value, Square): models.append(value) 课程,则必须测试类型名称,而不是更脆弱:

Square

如果你想真正推迟构造,而是稍后使用一组预设值构建它,请使用functools.partial()

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

如果您现在导入from models import Square from functools import partial somevariable = partial(Square, 'hello', 'there') 调用,则部分将应用已传入的参数并创建实例:

somevariable

答案 1 :(得分:0)

实际上你 在mymodule.py中实例化它,但它被丢弃了。要阻止你需要将创建的Square存储在带有名称的东西中,否则它将被垃圾收集,因为没有任何东西引用它。这就是我的意思:

mymodule.py:

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

然后您可以直接使用main.py中的名称直接访问它,如下所示:

main.py

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

答案 2 :(得分:0)

“想法是稍后实例化广场。”

您可以通过存储callable及其参数来实现。

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]