2013-06-27 5 views
2

Предварительно извиняется за сложные функции и методы, у меня нет времени на то, чтобы разобраться в терминологии, но я знаю разницу (как правило).Доступ к функции печати из глобальных переменных()

Я пытаюсь контролировать, какие функции выполняются моим скриптом через аргументы командной строки. После большого чтения здесь и в других местах я двигаюсь в направлении следующего примера.

# After connecting to a database with MySQLdb and defining a cursor... 

cursor.execute(some_query_stored_earlier) 
for row in cursor: 
    for method_name in processing_methods: # ('method1','method2', ...) 
     globals()[method_name](row) 

(Разъяснение:. processing_methods является кортежем определенных пользователем строк с помощью аргумента командной строки (ы) с nargs='*')

Однако, я бегу в проблемы с print (не удивительно там). Я хотел бы print быть:

  • среди методов, которые МОГУТ указываться из командной строки;
  • метод по умолчанию, когда методы NO указаны в командной строке;
  • не выполняется, если ТОЛЬКО ДРУГИЕ методы указаны в командной строке.

Позвольте мне признать, что я могу сделать вещи проще на себя, устраняя первый и третий критерии и просто делать:

for row in cursor: 
    print row 
    for method_name in processing_methods: 
     globals[method_name](row) 

Но я действительно не хочу, чтобы всегда печатать каждую строку в том, что будет иногда бывает результат в несколько миллионов строк. Я сделал будущий импорт, надеясь, что это решит мою проблему - нет такой удачи. Так что я сделал немного Исследуя:

>>> from __future__ import print_function 
>>> print 
<built-in function print> 

>>> globals() 
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'print_function': _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 65536), '__package__': None} 

>>> a = "Hello, world!" 
>>> print(a) 
Hello, world! 
>>> globals()['print'](a) 

Traceback (most recent call last): 
    File "<pyshell#33>", line 1, in <module> 
    globals()['print'](a) 
KeyError: 'print'    # Okay, no problem, obviously it's... 

>>> globals()['print_function'](a) 

Traceback (most recent call last): 
    File "<pyshell#34>", line 1, in <module> 
    globals()['print_function'](a) 
AttributeError: _Feature instance has no __call__ method # ...huh. 

Итак, я сделал немного больше читать, и this Q&A побудило некоторых больше исследования:

>>> dir() 
['__builtins__', '__doc__', '__name__', '__package__'] 
>>> __builtins__ 
<module '__builtin__' (built-in)> 
>>> 'print' in dir(__builtins__) 
True         # now we're getting somewhere! 
>>> __builtins__.print something 
SyntaxError: invalid syntax   # fair enough. 
>>> __builtins__.print('something') 
SyntaxError: invalid syntax   # wait, what? 
>>> dir(__builtins__.print) 
SyntaxError: invalid syntax   # -_- 

Что-то здесь происходит, что я просто не понимаю, и this other Q&A не стал более ясным. Я думаю, что простое решение для моей конкретной проблеме будет мягко неловко обёртку:

def printrows(row): 
    print row    # assuming no future import, of course 

Но это сводит меня с ума: Почему я не могу получить доступ к print через словарь глобалам? Я делаю это неправильно, или это просто то, что вы не можете сделать со встроенными функциями?

+1

Что такое 'processing_methods'? Белый список глобальных методов? Почему бы вам не преобразовать его в словарь «method_name» -> «реализация»? Этот способ будет немного более типичным, но вы сможете поддерживать более широкий спектр вариантов использования и поддерживать глобальную область чистой – J0HN

+0

Что-то вроде этого: http: // ideone.com/qu6u4o – J0HN

+0

@ J0HN 'print_function' неверно, поскольку фрагменты OP показывают, что это экземпляр' __future __._ Feature ', который является частью метаданных, а не функцией. Попробуйте это с помощью метода 'method = 'print'' и увидите, что он терпит неудачу. – delnan

ответ

2

Вы забыли повторить from __future__ import print_function, когда вы открыли новую оболочку для своей второй попытки (где вы получили все эти синтаксические ошибки)? Это работает для меня: https://ideone.com/JOBAAk

+0

Бинго. Я не совсем «забыл», поскольку пытался просуществовать поведение без будущего импорта. По какой-то причине я пренебрег поиском '__builtins__' снова с будущим импортом. – Air

1

Если вы делаете иначе бесполезное задание, оно работает так, как я думаю, вы ожидали. Я не эксперт в работе внутри здесь, поэтому я не могу объяснить ПОЧЕМУ это работает, но это так.

>>> from __future__ import print_function 
>>> row="Hello world" 
>>> print = print 
>>> globals()['print'](row) 
Hello world 
+0

Очень интересно! Он добавил '' print ': <встроенная функция print> 'в globals dict. Как вы столкнулись с этим поведением? – Air

+0

Я просто играл с кодом. Как я уже сказал, я не могу утверждать, что знаю внутреннюю причину, почему это работает. Казалось, что есть функция печати, на которую будут ссылаться при вызове, но «печать» в глобальном пространстве имен по-прежнему была встроенной. Кажется, что назначение заменяет встроенную в глобальное пространство импортированную функцию. – brechin