Я создаю подобную оболочке среду. Мой исходный метод handleing ввода данных пользователем состоял в том, чтобы использовать отображение словаря, управляет (представляет в виде строки) к методам различных классов, используя то, что функции являются объектами первого класса в Python.
Для пользы гибкости (главным образом для парсинга команд), я думаю об изменении моей установки, таким образом, что я использую getattr (команда), для захвата метода, в котором я нуждаюсь и затем передающие аргументы ему в конце моего синтаксического анализатора. Другое преимущество этого подхода не должно обновлять мой (в настоящее время статически реализованный) словарь команды каждый раз, когда я добавляю новый метод/команду.
Мой вопрос два, сворачиваются. Во-первых, getattr имеет те же проблемы как оценка? Во-вторых, я буду получать удар к эффективности моей оболочки? Имеет значение, сколько методов/команд я имею? Я в настоящее время смотрю 30 некоторые команды, которые могли в конечном счете удвоиться.
Разница между прямым доступом к атрибутам и использованием getattr () должна быть незначительной. Вы можете определить разницу между байт-кодами двух версий, используя модуль Python dis
для сравнения двух подходов:
>>> import dis
>>> dis.dis(lambda x: x.foo)
1 0 LOAD_FAST 0 (x)
3 LOAD_ATTR 0 (foo)
6 RETURN_VALUE
>>> dis.dis(lambda x: getattr(x, 'foo'))
1 0 LOAD_GLOBAL 0 (getattr)
3 LOAD_FAST 0 (x)
6 LOAD_CONST 0 ('foo')
9 CALL_FUNCTION 2
12 RETURN_VALUE
Однако это звучит так, будто вы разрабатываете оболочку, которая очень похожа на то, как Библиотека Python cmd
выполняет оболочки командной строки. cmd
позволяет создавать оболочки, выполняющие команды путем сопоставления имени команды с функцией, определенной в объекте cmd.Cmd
, например:
import cmd
class EchoCmd(cmd.Cmd):
"""Simple command processor example."""
def do_echo(self, line):
print line
def do_EOF(self, line):
return True
if __name__ == '__main__':
EchoCmd().cmdloop()
Вы можете узнать больше о модуле в любом из документацию или по адресу http://www.doughellmann.com/PyMOTW/cmd/index.html
имеет ли getattr те же проблемы, что и eval?
Нет - код, использующий eval()
, ужасно надоедает при поддержке и может иметь серьезные проблемы с безопасностью. Вызов getattr(x, "foo")
- это просто другой способ написать x.foo
.
не снизит ли это эффективность моей оболочки
Если команда не найдена, это будет незаметно медленнее, но не настолько, чтобы иметь значение. Вы заметите это только при выполнении бенчмарков с десятками тысяч записей.