2017-02-23 72 views
-1

我有一个脚本,可以使用或不使用命令行参数。这样说下面的“hello.py”:如何从一个python文件发送args到其他的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并将参数传递给它,使得“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'来分隔参数解析,你可以直接'import'并直接调用这个有用的函数。例如,'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

请勿在main中使用sys.argv;通过一个名称来代替它,这样

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