Python 方法参数管理

181 阅读2分钟

在 Python 中,我们经常会遇到需要编写一个方法,该方法可以被不同的参数组合调用。默认值取决于类属性的值。例如,有一个类 MyClass,其具有一个方法 my_method()my_method() 方法可以被调用,参数组合有以下几种:

huake_00198_.jpg

  • my_method(a, b, c):a、b 和 c 是必需的。
  • my_method(a, b, c, d, e):a、b 和 c 是必需的,d 和 e 是可选的(如果 self.a 的值为 something)。
  • my_method(a, b, c, e, f):a、b 和 c 是必需的,e 和 f 是可选的(如果 self.a 的值为 something else)。
  • e 的默认值取决于 self.a 的值。

目前的参数检查方式如下:

class MyClass:
    def __init__(self, ...):
        self.a = something

    def my_method(self, a, b, c, **kwargs):
        # a, b, and c are always required
        # if self.a = something, we have optional keyword arguments d and e
        # if self.a = something else, we have optional keyword arguments e and f
        # default for e depends on value of self.a

        # argument checking
        if self.a == something:
            if 'd' in kwargs.keys():
                d = kwargs['d']
            else:
                d = default value
            if 'e' in kwargs.keys():
                e = kwargs['e']
            else:
                e = default value
        else:
            if 'e' in kwargs.keys():
                e = kwargs['e']
            else:
                e = default value (different from above)
            if 'f' in kwargs.keys():
                f = kwargs['f']
            else:
                f = default value

这种方法很冗长,而且容易出错。有没有更好的方法来实现参数检查呢?

2、解决方案

一种方法是使用 dict 类的 get() 函数。get() 函数可以从字典中获取指定键的值,如果键不存在,则返回默认值。例如,可以将以下代码替换为:

if self.a == something:
    d = kwargs.get('d', defd)
    e = kwargs.get('e', defe1)
else:
    e = kwargs.get('e', defe2)
    f = kwargs.get('f', deff)

这样,代码就简洁了很多。

另一种方法是使用 functools.partial() 函数。partial() 函数可以将一个函数的部分参数固定,返回一个新的函数。例如,可以将以下代码替换为:

def my_method_with_d_and_e(self, a, b, c, d, e):
    # ...

def my_method_with_e_and_f(self, a, b, c, e, f):
    # ...

if self.a == something:
    my_method = functools.partial(my_method_with_d_and_e, self)
else:
    my_method = functools.partial(my_method_with_e_and_f, self)

my_method(a, b, c, **kwargs)

这样,就可以根据 self.a 的值来选择不同的函数来调用。

还有一种方法是使用 argparse 模块。argparse 模块可以帮助你解析命令行参数。例如,可以将以下代码替换为:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('a')
parser.add_argument('b')
parser.add_argument('c')
parser.add_argument('-d', default=defd)
parser.add_argument('-e', default=defe1)
parser.add_argument('-f', default=deff)

args = parser.parse_args()

my_method(args.a, args.b, args.c, **vars(args))

这样,就可以使用命令行参数来调用 my_method() 方法。