Python - Получение доступа к экземпляру класса через свойство модуля (по имени строки) - PullRequest
1 голос
/ 23 января 2011

Хорошо, позвольте мне попытаться объяснить это в меру своих возможностей.Допустим, у меня есть класс с именем 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: необязательный метод doIt () должен быть вызван с экземпляром Foobar в качестве первого аргумента.

Похоже, я получаю Foobar, но это не настоящий экземпляр.Любая помощь будет принята с благодарностью.Мне кажется, я достаточно подробно объяснил свой сценарий, так что вы видите более простой обход того, что я пытаюсь сделать, предложите его.

Ответы [ 3 ]

4 голосов
/ 23 января 2011

Как следует из комментария, вы, вероятно, столкнулись с именем между 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 голос
/ 24 января 2011

@ таблица поиска 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])
1 голос
/ 23 января 2011

Я не могу воспроизвести вашу ошибку (используя 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(...),
           ... } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...