繁体   English   中英

Python — 仅当变量存在时才传递参数

[英]Python — Only pass arguments if the variable exists

我有以下变量,用户可以选择通过表单提交这些变量(它们不是必需的,但可以这样做来过滤搜索)。

color = request.GET.get ('color')
size = request.GET.get ('size')

现在我想将这些变量传递给一个函数,但前提是它们存在。 如果它们不存在,我只想运行没有参数的函数。

没有参数的函数是:

apicall = search ()

只有颜色

apicall = search (color)

和颜色和大小

apicall = search (color, size)

如果定义了参数,我想将它传递给函数,但如果不是,我不想传递它。

最有效的方法是什么? python 有内置的方法吗?

假设这是一个标准的get调用(就像在字典上一样),这应该很容易。 使用None定义您的函数作为参数的默认值,然后传递colorsize而无需费心检查它们!

def apicall(color=None, size=None):
    pass # Do stuff

color = request.GET.get('color')
size = request.GET.get('size')
apicall(color, size)

这样,您只在一个地方检查None参数(在函数调用内部,无论如何您必须检查该函数是否可以通过多种方式调用)。 一切都保持美好和干净。 当然,这假设(就像我在顶部所说的那样)你的get调用就像一个普通的 Python 字典的get方法,如果没有找到值,它返回None

最后,我注意到您的函数名称是apicall :您可能实际上无法访问函数代码本身。 在这种情况下,由于您可能对函数签名的默认值一无所知,并且None可能是错误的,我可能只会编写一个简单的包装器来为您进行参数检查。 然后你可以像上面一样调用包装器!

def wrapped_apicall(color=None, size=None):
    if color is None and size is None:
        return apicall()
    # At least one argument is not None, so...
    if size is None:
        # color is not None
        return apicall(color)
    if color is None: 
        # size is not None
        return apicall(size)
    # Neither argument is None
    return apicall(color, size)

注意:除非您看不到正在调用的代码并且没有任何文档,否则不需要第二个版本! 使用None作为默认参数非常常见,因此您可能只使用第一种方式。 如果您无法修改正在调用的函数并且您不知道它的默认参数是什么(或者它的默认参数是模块常量或其他东西,但这种情况很少见),我只会使用包装器方法。

在 python 3 中,您可以将它们打包到一个列表中,对其进行过滤,然后使用* -operator 将列表解压缩为search参数:

color = request.GET.get ('color')
size = request.GET.get ('size')
args = [ arg for arg in [color, size] if arg ]
search(*args)

但是请注意,如果color为假而size为真,则您将使用 1 个参数作为size的值调用search ,这可能是错误的,但原始问题并未提及在这种情况下所需的行为。

(死灵,因为我正在寻找比我更好的解决方案,但发现了这个问题)

尽管我喜欢@HenryKeiter解决方案,但 Python 提供了一种更简单的方法来检查参数。 事实上,有几种不同的解决方案。

  1. 例如,如果search()是一个独立函数并且您想要查看参数,则可以使用此解决方案中所见的检查模块。

示例代码 1

>>> import inspect
>>> print(inspect.getfullargspec(search))

ArgSpec(args=['size', 'color'], varargs=None, keywords=None, defaults=(None, None))
  1. 但是,如果search()是一个类的方法(我们称之为Search ),那么您可以简单地使用内置的vars函数来查看所有类方法及其参数:

示例代码 2

>>> import Search
>>> print(vars(Search))

mappingproxy({'__init__': <function Search.__init__(self, size, color)>,
                  'search': <function Search.search(self, size, color)})

第二种方法的唯一警告是它作为视觉检查工具更有用,而不是编程工具,尽管从技术上讲,您可以说if 'size' in vars(Search)['search']: do something 它只是不会很健壮。 if 'size' in inspect.getfullargspec(Search.search).args: do somethingfor arg in inspect.getfullargsspec(Search.search).args: do somethingif 'size' in inspect.getfullargspec(Search.search).args: do something容易、更持久

也许您可以使用如下所示的内容:

try:
    apicall = search (color, size)
except:
    apicall = search(color)

当你定义你的方法时,如果你设置了一个默认参数,你可以指定或不指定参数。

def search(color=None, size=None):
    pass

然后,当您调用它时,您可以根据需要指定关键字参数。 这两个都是有效的:

apicall = search(color=color)
apicall = search(size=size)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM