2

我不确定这在 Python 中是否可行,我想知道,是否有任何方法可以在运行时检查参数是否传递给 Python 函数而不对参数值进行某种检查?

def my_func(req, opt=0):
    return was_opt_passed() # Returns bool 

print(my_func(0)) # Prints False
print(my_func(0, 0)) # Prints True

如果可能的话,这在某些情况下会更好,因为它消除了记住和检查哨兵值的需要。可能吗?

4

5 回答 5

1

正如马克在他的评论中已经说过的,典型的约定是使用默认值None。然后你可以检查它是否仍然None在调用。

def my_func(req, opt=None):
    if opt is None:
        #opt wasn’t passed.
        return False
    #opt was passed
    return True

尽管如果您想对其他选项进行更多研究(大多数情况下最不合常规),请随时查看这些答案

于 2019-09-09T18:09:12.853 回答
0

使用装饰器

    def check_opt_passed(methd):
        def m(req, *args, **kwarg):
            # this will check even if opt is passed as positional argument
            # and check if opt is passed not any other keyword
            if args or (kwarg and 'opt' in kwarg):
                print('opt is passed')
            else:
                print('opt is not passed')
            return methd(req, *args, **kwarg)

        return m

    @check_opt_passed
    def my_func(req, opt=0):
        # dummy expression for testing
        return req * opt


    print(my_func(1))           # opt is not passed
    print(my_func(1, 0))        # opt is passed
    print(my_func(1, opt=0))    # opt is passed
于 2019-09-09T18:05:18.007 回答
0

检测参数是否被传递的标准方法是哨兵值;但是,如果您愿意丢失函数签名,则可以使用**kwargs

def my_func(**kwargs):
  return 'opt' in kwargs
print(my_func()) #=> False
print(my_func(opt=0)) $=> True
于 2019-09-09T18:06:57.740 回答
0

一个很好的方法是使用 *args 或 **kwargs。

def was_opt_passed(*args, **kwargs):
  return len(args) > 0 or 'opt' in kwargs

def my_func(req, *args, **kwargs):
    return was_opt_passed(*args, **kwargs) # Returns bool 

print(my_func(0)) # Prints False
print(my_func(0, 0)) # Prints True
print(my_func(0, opt=0)) # Prints True
print(my_func(0, not_opt=0)) # Prints False

*args 收集传递给函数但尚未枚举的任何位置参数,而 **kwargs 收集传递给函数但尚未枚举的任何关键字参数。如果 args 包含位置参数,我们假设它是 opt 的,并且它必须已被传递。否则,如果它在 kwargs 中,它就通过了,然后如果我们在任何一个地方都没有找到它,那么它一定没有通过。

另请参阅https://docs.python.org/3/tutorial/controlflow.html#keyword-arguments

于 2019-09-09T18:03:01.907 回答
0

一种解决方案是使用装饰器/包装器。它们允许您与在运行时传递给您的函数的内容进行交互,然后按照您认为合适的方式处理所说的事情考虑以下代码:

def check_keywords(func):
    def wrapper(*args, **kwargs):
        if kwargs:
            print('Keyword was passed!')
        return func(*args, **kwargs)
    return wrapper

@check_keywords
def my_func(req, opt=0):
    print(req)

check_keywords捕获该函数,如果它检测到关键字被传递到my_func,它会打印一些东西。此打印语句可以转换为您想要的任意代码。

例如:

my_func(1)
>>> 1

my_func(1, opt = 1)
>>> Keyword was passed!
>>> 1
于 2019-09-09T18:03:18.967 回答