好的,让我尽力解释一下这个问题。假设我有一个名为Foobar的课程:
class Foobar():
def __init__(self, foo, bar, choo):
self.foo = foo
self.bar = bar
self.choo = choo
def doIt(self):
return self.foo + self.bar
我希望在我的应用程序中使用一组10个可能的Foobar实例。现在我的最终用户不知道或不关心foo,bar和choo的值,但是我想选择10个可能性中的一个,我将标记。
所以我想将他们的选择存储在db中(但我只想存储标签,它代表Foobar类的特定实例)。所以我可以抓住我需要的实例。
所以我尝试在这样的模块中设置我的所有实例(让我们称之为“my_instances.py”)
import Foobar
label_one = Foobar("eenie", "meenie", "miney")
label_two = Foobar("teeny", "toony", "tiny")
...
label_ten = Foobar("biggie", "boogie", "baggie")
就这样,一旦我有来自db的代表他们选择的字符串,我就可以像这样抓住那个实例(我忽略了你将如何得到字符串,但显示我是如何获取实例的)。
import my_instances
my_object = getattr(my_instances, 'label_one')
result = my_object.doIt()
我得到一个TypeError:必须使用Foobar实例作为第一个参数调用未绑定方法doIt()。
所以看来我正在接收Foobar,但不是真正的实例。任何帮助将不胜感激。我相信我已经足够解释了我的情况,你会看到我想要做的更简单的解决方法,请提出建议。
答案 0 :(得分:4)
正如评论所示,您可能在Foobar
班级和Foobar
模块之间发生名称冲突。
但是,明确定义查找表可能更清楚:
foobars = {
'label_one': Foobar("eenie", "meenie", "miney"),
'label_two': Foobar("teeny", "toony", "tiny"),
...
'label_ten': Foobar("biggie", "boogie", "baggie")
}
用法:
result = foobars['label_one'].do_it()
动态符号查找可以很聪明,但不一定更清晰。
答案 1 :(得分:1)
我无法重现您的错误(使用from foobar import Foobar
),因此您的代码中似乎没有向我们展示。但最好不要进行动态查找。为什么不创建一个返回foobar字典的工厂函数?
def get_foobars(x, y, z):
foobars = {}
foobars["label_one"] = Foobar(x, y, z)
foobars["label_two"] = Foobar(z, y, x)
...
或者,如果您不希望该功能每次都创建新的foobars,
foobars = {}
foobars["label_one"] = Foobar(...
def get_foobars():
return foobars
或者,更简洁,
foobars = {'label_one':Foobar("eenie", "meenie", "miney"),
'label_two':Foobar(...),
... }
答案 2 :(得分:1)
@ payne的查找表创建10个Foobar实例,然后返回你想要使用的实例;这似乎很浪费。为什么不按需实例化?
class Foobar():
def __init__(self, foo, bar, choo):
self.foo = foo
self.bar = bar
self.choo = choo
def doIt(self):
return self.foo + self.bar
makeFooLookup = {
"first": ("eenie", "meenie", "miney"),
"second": ("teeny", "toonie", "tiny"),
"third": ("biggie", "baggie", "boogie")
}
def makeFoo(label, lookup=makeFooLookup):
return Foobar(*lookup[label])