关于全局变量:在 python 中使用命令行参数标志的正确方法

Correct way to use command line argument flags in python

我有一组(4 个标志)标志,用于控制我的 python 脚本生成的输出的性质,以及控制脚本向终端打印多少信息的标志(通常使用 verbose 标志的方式)。这些标志被多个函数使用。标志的值由我使用 argparse.

解析的可选命令行参数设置

目前,我在任何使用标志的函数之外的全局范围内都有这些标志,而不是将标志作为参数传递给函数。像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import argparse
flag1=True
flag2=True
flag3=True

def fun1():
    ...
    if flag1:
        ..something..
    else:
        ..something else..
    #fun1 also uses the other flags in a similar way
    ...

def fun2():
    ...
    if flag2:
        ..something..
    else:
        ..something else..
    #fun1 also uses the other flags in a similar way
    ...

def main()
    ...
    args=parser.parse_args()
    ...
    global flag1
    flag1=args.flag1
    # and so on for the other flags
    fun1()
    fun2()

从这里的许多答案(例如,this)中,我一直认为在 python 中使用全局变量是不好的做法。这也适用于这里吗?我有点不愿意将标志作为参数传递,因为我将传递太多变量作为参数。

处理由命令行参数设置的标志的最佳方法是什么?


最简单的解决方案是将所有标志传递给所有函数(作为单个 args 对象)或仅根据哪个函数使用哪个标志传递相关标志。

现在这确实会成为一个很大的负担,特别是对于嵌套函数调用,在这种情况下,您很快就不得不将整个标志从一个函数传递到另一个函数...方法之间的状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Command(object):
    def __init__(self, flags):
        self.flags = flags

    def fun1(self):
        ...
        if self.flags.flag1:
            ..something..
        else:
            ..something else..

    def fun2(self):
        ...
        if self.flags.flag2:
            ..something..
        else:
            ..something else..


    def run(self):
        self.fun1()
        self.fun2()    

def main()
    ...
    args=parser.parse_args()
    cmd = Command(args)
    cmd.run()

我仍然是初学者,但关键字参数对我来说似乎是解决您问题的不错方法。我使用这样的东西:

1
2
3
4
5
6
7
8
9
10
11
12
def foo(**kwargs):
    verbose = kwargs.get('verbose', 0)  # set default value for your options
    if verbose > 2:
       print >> sys.stderr, 'some debug message or sth like that'
    if verbose > 0:
       print 'verbose note'  # for sth like 'your_app -v'

if __name__=='__main__'
    args=parser.parse_args()
    verbose = args.flag1
    foo(verbose=verbose)
    foo()