在 Python 中正确使用 **kwargs 的方法

2025-02-24 09:29:00
admin
原创
88
摘要:问题描述:**kwargs当谈到默认值时,在 Python 中正确的使用方法是什么?kwargs返回一个字典,但设置默认值的最佳方法是什么,或者有一种方法吗?我应该将其作为字典访问吗?使用get函数?class ExampleClass: def __init__(self, **kwargs): ...

问题描述:

**kwargs当谈到默认值时,在 Python 中正确的使用方法是什么?

kwargs返回一个字典,但设置默认值的最佳方法是什么,或者有一种方法吗?我应该将其作为字典访问吗?使用get函数?

class ExampleClass:
    def __init__(self, **kwargs):
        self.val = kwargs['val']
        self.val2 = kwargs.get('val2')

据我所知,人们在代码中使用不同的方法,很难知道该使用哪种。


解决方案 1:

get()您可以为字典中没有的键传递一个默认值:

self.val2 = kwargs.get('val2',"default value")

但是,如果您打算使用具有特定默认值的特定参数,为什么不首先使用命名参数呢?

def __init__(self, val2="default value", **kwargs):

解决方案 2:

虽然大多数答案都说,例如,

def f(**kwargs):
    foo = kwargs.pop('foo')
    bar = kwargs.pop('bar')
    ...etc...

和……相同

def f(foo=None, bar=None, **kwargs):
    ...etc...

这不是真的。在后一种情况下,f可以调用为f(23, 42),而前一种情况接受命名参数——没有位置调用。通常您希望允许调用者具有最大的灵活性,因此第二种形式(正如大多数答案所断言的那样)是可取的:但情况并非总是如此。当您接受许多可选参数(通常只传递几个)时,强制使用命名参数可能是一个好主意(避免在调用站点发生事故和代码不可读!)——threading.Thread就是一个例子。第一种形式是您在 Python 2 中实现它的方式。

这个习惯用法非常重要,以至于在 Python 3 中它现在有了特殊的支持语法:签名*中单个后面的每个参数def都是关键字参数,也就是说,不能作为位置参数传递,而只能作为命名参数传递。因此在 Python 3 中,你可以将上述代码编写为:

def f(*, foo=None, bar=None, **kwargs):
    ...etc...

事实上,在 Python 3 中你甚至可以拥有非可选的关键字参数(没有默认值的参数)。

然而,Python 2 在未来仍然有很长的生产寿命,所以最好不要忘记让你在 Python 2 中实现 Python 3 语言中直接支持的重要设计思想的技术和习语!

解决方案 3:

我建议这样的

def testFunc( **kwargs ):
    options = {
            'option1' : 'default_value1',
            'option2' : 'default_value2',
            'option3' : 'default_value3', }

    options.update(kwargs)
    print options

testFunc( option1='new_value1', option3='new_value3' )
# {'option2': 'default_value2', 'option3': 'new_value3', 'option1': 'new_value1'}

testFunc( option2='new_value2' )
# {'option1': 'default_value1', 'option3': 'default_value3', 'option2': 'new_value2'}

然后以任意方式使用值

dictionaryA.update(dictionaryB)添加的内容dictionaryBdictionaryA覆盖任何重复的键。

解决方案 4:

你会这样做

self.attribute = kwargs.pop('name', default_value)

或者

self.attribute = kwargs.get('name', default_value)

如果您使用pop,那么您可以检查是否发送了任何虚假值,并采取适当的措施(如果有)。

解决方案 5:

使用 kwargs 和默认值很容易。但是,有时你不应该首先使用 kwargs。

在这种情况下,我们并没有真正充分利用**kwargs。

class ExampleClass( object ):
    def __init__(self, **kwargs):
        self.val = kwargs.get('val',"default1")
        self.val2 = kwargs.get('val2',"default2")

以上是“为什么要费心?”的声明。它与

class ExampleClass( object ):
    def __init__(self, val="default1", val2="default2"):
        self.val = val
        self.val2 = val2

当您使用 **kwargs 时,您意味着关键字不仅是可选的,而且是条件性的。有比简单的默认值更复杂的规则。

当您使用 **kwargs 时,您通常意味着更类似于以下内容,其中简单的默认值不适用。

class ExampleClass( object ):
    def __init__(self, **kwargs):
        self.val = "default1"
        self.val2 = "default2"
        if "val" in kwargs:
            self.val = kwargs["val"]
            self.val2 = 2*self.val
        elif "val2" in kwargs:
            self.val2 = kwargs["val2"]
            self.val = self.val2 / 2
        else:
            raise TypeError( "must provide val= or val2= parameter values" )

解决方案 6:

因为**kwargs在参数数量未知时使用,为什么不这样做呢?

class Exampleclass(object):
  def __init__(self, **kwargs):
    for k in kwargs.keys():
       if k in [acceptable_keys_list]:
          self.__setattr__(k, kwargs[k])

解决方案 7:

这是另一种方法:

def my_func(arg1, arg2, arg3):
    ... so something ...

kwargs = {'arg1': 'Value One', 'arg2': 'Value Two', 'arg3': 'Value Three'}
# Now you can call the function with kwargs like this:

my_func(**kwargs)

解决方案 8:

我认为在 Python 中使用默认值的正确方法**kwargs是使用字典方法setdefault,如下所示:

class ExampleClass:
    def __init__(self, **kwargs):
        kwargs.setdefault('val', value1)
        kwargs.setdefault('val2', value2)

这样,如果用户在关键字中传递了‘val’或‘val2’ args,那么将使用它们;否则,将使用已设置的默认值。

解决方案 9:

按照@srhegde关于使用setattr的建议:

class ExampleClass(object):
    __acceptable_keys_list = ['foo', 'bar']

    def __init__(self, **kwargs):
        [self.__setattr__(key, kwargs.get(key)) for key in self.__acceptable_keys_list]

当预期该类别包含列表中的所有项目时,此变体很有用acceptable

解决方案 10:

你可以做这样的事情

class ExampleClass:
    def __init__(self, **kwargs):
        arguments = {'val':1, 'val2':2}
        arguments.update(kwargs)
        self.val = arguments['val']
        self.val2 = arguments['val2']

解决方案 11:

如果您想将其与 args 结合起来,则必须将 args 和 **kwargs 保留在定义的末尾。

所以:

def method(foo, bar=None, *args, **kwargs):
    do_something_with(foo, bar)
    some_other_function(*args, **kwargs)

解决方案 12:

处理未知或多个参数的另一种简单解决方案是:

class ExampleClass(object):

    def __init__(self, x, y, **kwargs):
      self.x = x
      self.y = y
      self.attributes = kwargs

    def SomeFunction(self):
      if 'something' in self.attributes:
        dosomething()

解决方案 13:

**kwargs 允许自由添加任意数量的关键字参数。可以有一个键列表,可以为其设置默认值。但为无限数量的键设置默认值似乎没有必要。最后,将键作为实例属性可能很重要。因此,我将按如下方式执行此操作:

class Person(object):
listed_keys = ['name', 'age']

def __init__(self, **kwargs):
    _dict = {}
    # Set default values for listed keys
    for item in self.listed_keys: 
        _dict[item] = 'default'
    # Update the dictionary with all kwargs
    _dict.update(kwargs)

    # Have the keys of kwargs as instance attributes
    self.__dict__.update(_dict)

解决方案 14:

@AbhinavGupta 和 @Steef 建议使用update(),我发现这对于处理大型参数列表非常有帮助:

args.update(kwargs)

如果我们想检查用户是否传递了任何虚假/不受支持的参数,该怎么办?@VinaySajip 指出,pop()可用于迭代处理参数列表。然后,任何剩余的参数都是虚假的。很好。

这是实现此目的的另一种可能的方法,它保留了使用的简单语法update()

# kwargs = dictionary of user-supplied arguments
# args = dictionary containing default arguments

# Check that user hasn't given spurious arguments
unknown_args = user_args.keys() - default_args.keys()
if unknown_args:
    raise TypeError('Unknown arguments: {}'.format(unknown_args))

# Update args to contain user-supplied arguments
args.update(kwargs)

unknown_args包含set默认值中未出现的参数名称。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2757  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1693  
  在全球化的浪潮下,企业的业务范围不断拓展,跨文化协作变得愈发普遍。不同文化背景的团队成员在合作过程中,由于语言、价值观、工作习惯等方面的差异,往往会面临诸多沟通挑战。而产品生命周期管理(PLM)系统作为企业管理产品全生命周期的重要工具,如何有效支持跨文化协作成为了关键问题。通过合理运用沟通策略,PLM系统能够在跨文化团...
plm是什么软件   15  
  PLM(产品生命周期管理)系统在企业的产品研发、生产与管理过程中扮演着至关重要的角色,其中文档版本控制是确保产品数据准确性、完整性和可追溯性的关键环节。有效的文档版本控制能够避免因版本混乱导致的错误、重复工作以及沟通不畅等问题,提升企业整体的运营效率和产品质量。接下来,我们将深入探讨 PLM 系统实现文档版本控制的 6...
plm是什么意思   19  
  PLM(产品生命周期管理)项目管理旨在通过有效整合流程、数据和人员,优化产品从概念到退役的整个生命周期。在这个过程中,敏捷测试成为确保产品质量、加速交付的关键环节。敏捷测试强调快速反馈、持续改进以及与开发的紧密协作,对传统的测试流程提出了新的挑战与机遇。通过对测试流程的优化,能够更好地适应PLM项目的动态变化,提升产品...
plm管理系统   18  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用