Cap*_*oom 6 python program-entry-point
函数名是否应该main()为空并且在函数本身内调用参数,或者将它们作为函数的输入是否可接受main(arg1, arg2, arg3)?
我知道它有效,但我想知道它是不是很糟糕的编程习惯.如果这是重复的道歉,但我看不出专门针对Python的问题.
在大多数其他编程语言中,您要么有零个参数,要么有两个参数:
int main(char *argv[], int argc)
Run Code Online (Sandbox Code Playgroud)
表示传递给参数的参数。但是,在 Python 中,这些是通过sys模块访问的:
import sys
def main():
print(sys.argv, len(sys.argv))
Run Code Online (Sandbox Code Playgroud)
但是你可以扩展它,这样你就可以将 argv 和 argc 传递到你的 python 函数中,类似于其他语言是的:
import sys
def main(argv, arc):
print(argv, arc)
if __name__ == '__main__':
main(sys.argv, len(sys.argv))
Run Code Online (Sandbox Code Playgroud)
但是让我们暂时忘记 argv/argc -为什么要将某些内容传递给 main。您在 main 之外创建了一些东西,并希望将它传递给 main。这可能发生在两种情况下:
main要传递的外部创建了变量。第 1 点绝对是不好的做法。main应该是唯一的并且只在程序开始时调用一次。如果需要多次调用,那么里面的代码main就不属于 inside main。把它分开。
第 2 点可能看起来有道理,但是您在实践中这样做:
def main(a, b):
print(a, b)
if __name__ == '__main__':
x = 4
y = 5
main(x, y)
Run Code Online (Sandbox Code Playgroud)
但是不是x和y全局变量吗?好的做法是假设这些位于文件的顶部(以及多个其他属性 - 它们是常量等),并且您不需要将它们作为参数传递。
通过遵循以下模式:
def main():
...stuff...
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)
它允许您的脚本直接运行,并且如果使用安装工具打包,则可以在通过指定 main 作为入口点安装包时自动生成可执行脚本。
请参阅:https ://setuptools.readthedocs.io/en/latest/setuptools.html#automatic-script-creation
您可以添加setup.py以下内容:
entry_points={
'console_scripts': [
'my_script = my_module:main'
]
}
Run Code Online (Sandbox Code Playgroud)
2023 编辑:诗歌等较新的打包工具也遵循相同的模式:https ://python-poetry.org/docs/pyproject#scripts
然后,当您构建一个包时,人们可以将其安装在他们的虚拟环境中,并立即在他们的路径上调用一个脚本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()
Run Code Online (Sandbox Code Playgroud)
这允许您直接运行脚本,自动生成一个行为相同的脚本,还可以导入脚本并调用do_stuff以重用或测试实际功能。
评论中提到了这篇博文:https://www.artima.com/weblogs/viewpost.jsp ?thread=4829,它使用 main 上的默认参数来允许依赖注入进行测试,但是,这是一个非常古老的博客邮政; 从那时起,该getopt图书馆已被取代两次。这种模式更优越,并且仍然允许依赖注入。