在Python中的main()中调用参数是否不好

时间:2018-11-08 09:27:56

标签: python main

函数名称main()始终为空,是否在函数本身内调用了参数,还是可以将它们作为函数的输入,例如main(arg1, arg2, arg3)

我知道它有效,但是我想知道这是否是不良的编程实践。抱歉,如果这是重复的,但我看不到专门针对Python的问题。

3 个答案:

答案 0 :(得分:3)

在大多数其他编程语言中,您将具有零个参数或两个参数:

int main(char *argv[], int argc)

表示传递给参数的参数。但是,在Python中,这些是通过sys模块访问的:

import sys

def main():
    print(sys.argv, len(sys.argv))

但是您可以扩展它,以便将argv和argc传递到python函数中,类似于其他语言,是的:

import sys

def main(argv, arc):
    print(argv, arc)

if __name__ == '__main__':
    main(sys.argv, len(sys.argv))

但是暂时让我们忘记argv / argc-为什么要将某些内容传递给main。您在main之外创建一些东西,并希望将其传递给main。这可能在两种情况下发生:

  1. 您正在从其他函数多次调用main。
  2. 您已经在main之外创建了要传递的变量。

第1点绝对不是一个好习惯。 main应该是唯一的,并且在程序开始时只能被调用一次。如果您需要多次调用它,则main中的代码不属于main内部。拆分。

第2点似乎很有意义,但是您要切实地做到这一点:

def main(a, b):
    print(a, b)

if __name__ == '__main__':
    x = 4
    y = 5
    main(x, y)

但是xy全局变量不是吗?优良作法是假设它们位于文件的顶部(以及其他多个属性-它们是常量,等等),并且您不需要将它们作为参数传递。

答案 1 :(得分:0)

按照模式:

def main():
    ...stuff...

if __name__ == '__main__':
    main()

它允许您的脚本直接运行,如果使用安装工具打包,则可以通过指定main作为入口点在安装包时自动生成可执行脚本。

请参阅:https://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation

您将在setup.py中添加以下内容:

entry_points={
    'console_scripts': [
        'my_script = my_module:main'
    ]
}

然后,当您构建软件包时,人们可以将其安装在虚拟环境中,并立即在其路径上获得一个名为my_script的脚本。

像这样的自动脚本创建需要一个不需要必需参数的函数。

一个好主意是允许您导入脚本并公开其功能,以供代码重用和测试。我会建议在此模式下添加一些东西

import argparse

def parse_args():
    parser = argparse.ArgumentParser()
    #
    # ... configure command line arguments ...
    #
    return parser.parse_args()

def do_stuff(args):
    #
    # ... main functionality goes in here ...
    #

def main():
    args = parse_args()
    do_stuff(args)

if __name__ == '__main__':
    main()

这使您可以直接运行脚本,具有行为相同的自动生成的脚本,还可以导入脚本并调用do_stuff以重用或测试实际功能。

以下评论中提到了该博客文章:https://www.artima.com/weblogs/viewpost.jsp?thread=4829,它在main上使用默认参数以允许依赖项注入进行测试,但是,这是一个非常古老的博客文章(getopt库已经从那以后被取代两次),我认为这种模式更好。

答案 2 :(得分:0)

我绝对希望看到main接受争论,而不是直接访问sys.argv

这使得其他Python模块对main函数的重用变得更加容易。

import sys

def main(arg):
    ...

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

现在,如果我想将此模块作为另一个模块中的脚本执行,我可以编写(在另一个模块中)。

from main_script import main

main("use this argument")

如果main使用sys.argv,这会更困难。