如何获取传递给函数的参数

3

在Python中,有没有一种方法可以获取调用者传递给函数的参数? 这是我正在尝试做的事情:

# function
def repeat(self, min=None, max=None, optional=False):
    do_something()

我需要根据是否传递了一个或多个参数来做出不同的操作。例如:

r.repeat('hello').repeat(2,None)

需要区分以下几点:

r.repeat('hello').repeat(2) # only one arg passed

我认为locals可能是一个好的起点,但它会获取函数的默认参数,因此对我的目的没有用:

{'_max': None, '_min': 2, 'discrete': [], 'optional': False, 'max': None, 'min': 2, 'self': r'(hello)'}

换句话说,max 不应该出现在参数中。这在 Python 中是否可行?我还尝试使用 inspect,但那似乎也会显示默认值:
(Pdb) inspect.getargvalues(f)
ArgInfo(args=['self', 'min', 'max', 'optional', 'discrete'], varargs=None, keywords=None, locals={'pdb': <module 'pdb' from '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pdb.py'>,
 '_max': None, '_min': 2, 'discrete': [], 'optional': False, 'max': None, 'min': 2, 'self': r'(hello)', 'f': <frame object at 0x101e2de68>})

1
据我所知,Python 内部并不跟踪默认参数和实际传递的参数,所以我认为 inspect 无法帮助此处,因为 None 既是默认参数,也是有效输入参数。使用一个 哨兵对象 代替 None 作为默认值,正如 这个答案 所建议的那样,是我见过的最常见的解决方法。 - SethMMorton
1个回答

1
我认为有更简单的解决方案可以解决您的问题。我知道的最简单的方法是设置一个默认值,该值不可能作为实际参数传递。创建一个虚拟对象并将其用作默认值:
dummy_default = object()

def my_function(x=dummy_default):
    actual_x = None if x is dummy_default else x
    # ...

这样,如果没有传递参数或显式传递了 Noneactual_x 将为 None。但是,您可以通过测试 x is dummy_default 来区分这些情况。
您也可以使用*vargs:
def my_function(*vargs):
    if len(vargs) > 1:
        raise TypeError('Too many arguments')
    x = vargs[0] if len(vargs) >= 1 else None
    # ...

表达式len(vargs) == 0将告诉您是否未传递任何参数。
这种方法稍微差一些,因为使关键字参数也起作用更加复杂,如果使用IDE,则无法获得有用的参数提示,并且您需要自行处理错误数量的参数。

同意。每次我需要做像OP想要做的事情时,最终都不得不使用这两种方法之一。 - SethMMorton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接