Более питонический способ построить класс на основе строки (как не использовать eval) - PullRequest
1 голос
/ 12 декабря 2011

ОК.

Итак, у меня есть база данных, в которой я хочу хранить ссылки на другие объекты Python (сейчас я использую для хранения информации об инвентаре персональные хранилища ингредиентов рецептов пива).

Поскольку существует около 15-20 различных категорий ингредиентов (все они представлены отдельными объектами SQLO), я не хочу делать кучу столбцов RelatedJoin, поскольку я ленив, и, похоже, это не«лучшее» или «питоническое» решение как оно есть.

Итак, сейчас я делаю это:

class Inventory(SQLObject):
    inventory_item_id = IntCol(default=0)
    amount = DecimalCol(size=6, precision=2, default=0)
    amount_units = IntCol(default=Measure.GM)
    purchased_on = DateCol(default=datetime.now())
    purchased_from = UnicodeCol(default=None, length=256)
    price = CurrencyCol(default=0)
    notes = UnicodeCol(default=None)
    inventory_type = UnicodeCol(default=None)

    def _get_name(self):
        return eval(self.inventory_type).get(self.inventory_item_id).name

    def _set_inventory_item_id(self, value):
        self.inventory_type = value.__class__.__name__
        self._SO_set_inventory_item_id(value.id)

Обратите внимание на ICKY eval() в методе _get_name ().

Как мне поступить с вызовом класса SQLObject, на который ссылается строка, которую я получаю из __class__.__name__, без использования eval()?Или это подходящее место для использования eval()?(Я в некотором роде настроение, когда никогда не уместно использовать eval() - однако, поскольку система никогда не использует ввод конечного пользователя в eval(), это кажется "безопасным".)

1 Ответ

3 голосов
/ 12 декабря 2011

Получить значение глобального по имени; Использование:

globals()[self.inventory_type]
...