【问题标题】:Can I Skip Parameters in Python When Using Kwargs使用 Kwargs 时我可以跳过 Python 中的参数吗
【发布时间】:2019-02-14 00:55:22
【问题描述】:

我有一个接收 kwargs 的函数。我想按名称使用 kwargs 参数,而不必将每个参数显式声明为参数或变量。有没有办法通过传入 kwargs 来使用 my_var_key,而不必在函数调用中专门定义它,或者是使用 kwargs[ "my_var_key" ] 的唯一方法?

例如我想要类似的东西

def func(**kwargs):
    print(my_var_key)

相对

def func(my_var_key, **kwargs):
    print(my_var_key)

def func(**kwargs):
    print(kwargs[ "my_var_key" ])

如果密钥不存在,我可以破坏它。

【问题讨论】:

  • 你为什么不直接传入一本字典并在该字典上工作?
  • 您可以通过将代码包装在try ... except NameError 中来捕获NameErrorparse the NameError error message to extract the variable name,然后在kwargs 中查找提取的名称...易碎,我不确定那会给你带来什么。除了减少打字之外,还有其他动机吗?
  • @jamesdlin 为了激励,假设(这是为了说明的极端情况)你有五个函数,每个函数都接受 100 个参数。假设这些参数中的大多数将是相同的关键字,但某些参数将存在,而其他参数不存在。这些功能也以非常不同的方式使用它们。我不想明确声明 100 个变量五次,但是有太多独特的参数使得做一个公共子集也值得。最好的办法是拥有一个包含所有常用参数和唯一参数的 kwargs 字典,默认为空值,并将其传递给每个函数。
  • 我可能会尝试使用装饰器来减少样板。

标签: python function dictionary parameters keyword-argument


【解决方案1】:

不,没有实用的方法可以得到你想要的语法。

Python's design philosophy 的一部分是“显式优于隐式”,因此在没有您输入的情况下名称会添加到您的命名空间的情况并不多。如果您希望在将 my_var_key 作为参数传递时将其放入函数的命名空间,您只需在 def 语句中命名即可。如果您希望它只能作为关键字参数(而不是位置参数)传递,您可以在参数列表中放置 *

def func(*, my_var_key): # arg can only be passed as a keyword: func(my_var_key=1)
   ...

【讨论】:

    【解决方案2】:

    不要这样做。它使您的代码更难阅读。

    但如果您坚持,请尝试修改您的 globals() 范围:

    def func(**kwargs):
        for key, val in kwargs.items():
            globals()[key] = val
        print(globals())
        print(my_var_key)
    
    func(my_var_key='foobar')
    

    输出是:

    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x10f058f28>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'test.py', '__cached__': None, 'func': <function func at 0x10ef52268>, 'my_var_key': 'foobar'}
    foobar
    

    这肯定会污染你的全局命名空间(你不能使用locals(),因为解释器会混淆)。同样,不要这样做。

    【讨论】:

    • 为什么还要发布这个答案?
    • @juanpa.arrivillaga 很高兴知道一种语言有什么可能,即使实际上这样做并不是最佳实践
    猜你喜欢
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 2014-06-29
    • 1970-01-01
    相关资源
    最近更新 更多