【问题标题】:Python - Getting access to class instance via module property (by string name)Python - 通过模块属性(通过字符串名称)访问类实例
【发布时间】:2011-01-23 03:27:30
【问题描述】:

好的,让我尽我所能解释一下。假设我有一个名为 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 种可能性中的一种,我将对其进行标记。

所以我想将他们的选择存储在数据库中(但我只想存储标签,它代表 Foobar 类的特定实例)。这样我就可以获取我需要的实例。

所以我尝试在这样的模块中设置我的所有实例(我们称之为“my_instances.py”)

import Foobar

label_one = Foobar("eenie", "meenie", "miney")
label_two = Foobar("teeny", "toony", "tiny")
...
label_ten = Foobar("biggie", "boogie", "baggie")

这样,一旦我从数据库中获得了代表他们选择的字符串,我就可以像这样获取该实例(我忽略了您将如何获取该字符串,但展示了我如何获取该实例)。

import my_instances

my_object = getattr(my_instances, 'label_one')
result = my_object.doIt()

我得到一个 TypeError: unbound method doIt() must be called with Foobar 实例作为第一个参数。

所以看起来我正在获取 Foobar,但不是它的真实实例。任何帮助将不胜感激。我相信我已经充分解释了我的情况,您会看到我正在尝试做的更简单的解决方法,请提出建议。

【问题讨论】:

  • 试试from Foobar import Foobar
  • 我可能表现不佳,但没有名为 Foobar 的模块,只有一个类

标签: python class attributes module instance


【解决方案1】:

正如评论所暗示的,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()

动态符号查找可能很聪明,但不一定更清晰。

【讨论】:

    【解决方案2】:

    @payne 的查找表创建十个 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])
    

    【讨论】:

    • 你能解释一下最后一行中的星号是做什么的吗?
    • 它将元组解包成单独的参数,以便 Foobar.__init__ 接收 foo="eenie", bar="meenie", choo="miney" 而不是 foo = tuple("eenie"," meenie","miney"), bar = !missing argument!, choo = !missing argument!
    【解决方案3】:

    我无法重现您的错误(使用from foobar import Foobar),因此您的代码中似乎有些内容您没有向我们展示。但最好还是不要进行动态查找。为什么不创建一个返回 foobars 字典的工厂函数?

    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(...),
               ... } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-31
      • 2016-07-30
      • 1970-01-01
      • 2014-06-04
      • 2019-12-08
      • 1970-01-01
      • 2022-07-22
      • 2023-03-17
      相关资源
      最近更新 更多