2017-02-23 205 views
-1

У меня есть скрипт, который может работать с аргументами командной строки или без них. Скажи что-то вроде следующих «hello.py»:Как отправить args из одного файла python в sys.argv другого

#!/usr/bin/python 
# This is hello.py. 

import sys 

# Define a main() function that prints a little greeting. 
def main(): 

    if len(sys.argv) >= 3: 
     print "Incorect usage." 

    if len(sys.argv) == 2: 
     name = sys.argv[1] 
     print "Hi " + name + ", and Hello world!!!" 
    else: 
     print "Hello World!!!" 


# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

Теперь я намерен написать «wrapper.py», что импорт «hello.py» и в свою очередь, вызывает привет. Я хочу вызвать привет и передать аргументы, чтобы «hello.py» все еще мог использовать логику в sys.argv. Скажите что-нибудь вроде следующего.

#!/usr/bin/python 
# This is wrapper.py. 

import sys 
import hello 

# Define a main() function that prints a little greeting. 
def main(): 

    hello.main()  # This prints "Hello World!!!" 

    name = "Harry" 
    # hello.main? 
    # How to print "Hi Harry, and Hello world!!!? 
    # I want to call main from here and pass and name to it that it picks from sys.argv. 
    # I don't want to do os.system("python hello.py Harry"). 
    # I don't want to do subprocess.Popen("python hello.py Harry", shell=True).communicate() 
    # I don't want to define a new function in hello.py that accepts variable args. 
    # I want to make preferably no changes to hello.py. 
    # Thus I want to somehow call hello.main from here such that it still can pick 
    # args from sys.argv. 

# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

Как я могу это достичь? Есть ли правильный или чистый способ сделать это?

+0

Почему вы хотите сделать это так? Если вы рефакторируете 'hello.py', чтобы разделить парсинг аргументов, вы можете просто« импортировать »и вызвать полезную функцию напрямую. Например, 'def main (name):' и 'if __name__ == '__main__': main (parse_args())' – jonrsharpe

+0

Можете ли вы объяснить, почему ни один из нескольких простых методов не подходит для ваших целей? – TigerhawkT3

+0

@Tigerhawk: os.system и subprocess.Popen для меня выглядит обходным путем из-за недостатка моих знаний. Я буду очень удивлен, если args нельзя передать другому сценарию через sys.argv. Возможно, какой-то контекст должен быть создан до вызова. Я не хочу использовать функцию-оболочку в «hello.py», так как это приведет к двуличности кода в main и функции с переменными args. Код, который я создал здесь, представляет собой упрощенное представление о том, что я пишу, и точно фиксирует вопрос в контексте. Любая двуличность кода удваивает затраты на его поддержание. –

ответ

2

Не использовать sys.argv в main; передать имя ему вместо этого, как этот

def main(name=None): 

    if name: 
     print "Hi " + name + ", and Hello world!!!" 
    else: 
     print "Hello World!!!" 

if __name__ == '__main__': 
    # Put here the logic of checking the input arguments to the program, 
    # all your "if len(sys.argv) >= 3 ..." stuff 
    if len(sys.argv) == 2: 
     main(sys.argv[1]) 
    else: 
     main() 

Затем в обертке просто позвоните hello.main("Harry")

1

Вы неправильно определили вашу проблему; возможно, он становится яснее, если мы переименуем функцию main, чтобы описать то, что он на самом деле делает:

def parse_arguments_and_display_output(): 
        #^this is a bad sign 

Вашей функция имеет два несвязанных проблем: аргументы разбора и отображающих выход. Вместо этого мы можем реорганизовать его ввести две новые функции:

def main(): 
    name = parse_arguments() 
    display_output(name) 

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

from hello import display_output 

if __name__ == '__main__': 
    display_output('Harry') 

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


Обратите внимание, что вы можете использовать argparse взять один позиционный аргумент, и это на самом деле не намного больше коды, чем вы в настоящее время пишете:

import argparse 

def parse_arguments(): 
    parser = argparse.ArgumentParser(description='Enter your name') 
    parser.add_argument('name', nargs='?', help='your name') 
    return parser.parse_args().name 

Также вы получаете хорошую помощь:

usage: python.py [-h] name 

Enter your name 

positional arguments: 
    name  your name 

optional arguments: 
    -h, --help show this help message and exit