2015-03-10 3 views
0

У меня есть несколько сценариев, которые ссылаются на программу Python с помощью:Обновление Python CLI, сохраняя при этом "питон -c exectfile" интерфейс

python -c "execfile('myfile.py'); readFunc(param='myParam', input='blahblah')"

интерфейс. То, что я хотел бы сделать, концептуально просто: разработать более модульную систему с «основным» и обычным интерфейсом CLI Python, который затем вызывает эти функции, но также ОСНОВАЕТ существующий интерфейс, поэтому скрипты, созданные для его использования, все еще работают.

Возможно ли это?

В идеале, если бы я должен был назвать

python myFile readFunc myParam blabblah 

Было бы что-то вроде:

main(sys.argv): 
    readFunc(sys.argv[2], sys.arg[3]) 

Я пытался что-то подобное, но это не совсем сработало. Возможно ли поддерживать оба интерфейса/методы вызова?

Спасибо!

ответ

0

Первая идея, которая приходит на ум, связана с необязательными аргументами функции execfile(). Вы могли бы быть в состоянии сделать что-то вроде этого:

#!python 
def main(args): 
    results = do_stuff() 
    return results 

if __name__ == '__main__': 
    import sys 
    main(sys.argv[1:]) 

if __name__ == 'execfile': 
    main(args) 

... и тогда, когда вы хотите вызвать его через execfile() вы поставляете словарь для опционального globals аргумента:

#!sh 
python -c 'execfile(myfile, {"__name__":"execfile", "args":(1,2,3)}); ...' 

Это требует немного дополнительной работы, когда вы вызываете свою функциональность через -c, поскольку вы должны помнить, что этот словарь и переезд '__name__' ... через, я полагаю, вы действительно можете использовать любой действительный идентификатор Python. Просто __name__ ближе всего к тому, что вы на самом деле делаете.

Следующая идея выглядит немного грязной, но опирается на кажущуюся обработку глобального идентификатора. Кажется, что оно отменяется при вызове python -c и устанавливает, будет ли файл импортироваться или выполняться. Так это работает (по крайней мере, для CPython 2.7.9):

#!/usr/bin/env python 
foo='foo' 
if __name__ == '__main__' and '__file__' not in globals(): 
    print "Under -c:", foo 

elif __name__ == '__main__': 
    print "Executed standalone:", foo 

... и если вы используете что, пожалуйста, не дайте мне кредит. Это выглядит ...

... ... мммм ....

... просто ...

.... НЕПРАВИЛЬНО

+0

Следует отметить, что строка «execfile» для '__name__' здесь абсолютно произвольна, и вам может быть даже лучше использовать строку, которая никогда не столкнется с именем любого модуля, в который может быть импортирован ваш код. Возможно, просто «*» ... буквальная строка звездочки. –

+0

Да, дело в том, что исполняемый интерфейс execfile должен быть настойчивым. Если мы собираемся изменить его, мы могли бы полностью отказаться от него и довести вещи до 21-го века в любом случае. Я буду настаивать на этом, но на этом интерфейсе построено много сценариев, поэтому было бы лучше сделать это параллельно. – user770901

+0

Вы можете что-то делать с '__name__' ==' '__main __ '' и '' __file __' 'не в globals(). Я добавляю образец к моему сообщению. –

0

Если я понимаю это один

python myFile readFunc myParam blabblah 

правильно, вы хотите, чтобы разобрать argv[1] как имя команды для выполнения.

Так просто сделать

if __name__ == '__main__': 
    import sys 
    if len(sys.argv) < 2 or sys.argv[1].lower() == 'nop' or sys.argv[0] == '-c': # old, legacy interface 
     pass 
    elif sys.argv[1].lower() == 'readfunc': # new one 
     readFunc(sys.argv[2:]) 

, где вторая часть запускается на выполнение на непосредственное выполнение файла (либо через python file.py readFunc myParam blabblah или через python -m file readFunc myParam blabblah)

«NOP»/пустой argv отрасль приходит играть при использовании «старого» интерфейса: в этом случае вы, скорее всего, не указали аргументы cmdline и, следовательно, можете предположить, что вы ничего не хотите выполнять.

Выполняет эту задачу по-прежнему: идентификатор readFunc экспортируется и может использоваться в скрипте -c, как и раньше.