python的**kwargs效率

2024-03-29 11:04:54 发布

您现在位置:Python中文网/ 问答频道 /正文

像这样建立Python的流程行吗?在

def foo(**kwargs):
    kwargs['kw'] = 1
    return bar(**kwargs, wk=2)
def bar(**kwargs):
    process(1,2,'sss',**kwargs)
    for i in kwargs:
        print(i)
...etc...

kwargs是去一个可变对象(dict)并且只有它的引用会传递到流中,还是我将被解包并反复创建?在

更精确的问题。如果我这样做:

^{pr2}$

一次只有一次口述吗?如果是这样的话,每次调用都会创建新的对象吗? 还是我把它们堆起来?在

实际情况是,我是与AVRO通信的子服务之一。所以我有一个包,可以将这个二进制文件转换成dict,然后我需要做一些事情并创建一个新的AVRO。在

有些字段在新模式中不存在,有些字段是添加的,有些字段只是传递而不接触它们。在

所以我只需要第一个dict,一遍又一遍地添加越来越多的数据,最后我有了另一个模式,avro包可以接受如此巨大的dict,并且只序列化模式中定义的内容。在

这种方法行吗?在


Tags: 对象forreturnfoodef模式bar流程
3条回答

很容易直接找出发生了什么:

def a(**kwargs):
    b(**kwargs)
    print(kwargs)  # prints {'x': 1}, not {'x': 1, 'y': 2}

def b(**kwargs):
    kwargs['y'] = 2

a(x=1)

所以每次都有一个新的口述。在

为每个函数中的每个**kwargs参数构建一个新字典。这是因为call**kwargs语法与函数签名中的语法不同

  • 在call中使用**kwargs会导致字典被解压为单独的关键字参数。在
  • 使用**kwargs作为catch all参数会导致从传入的关键字参数生成字典。在

即使不是这样,Python也不能通过共享字典来优化。函数foo()调用bar()必须处理传递到调用中的字典kwargs可能发生变化的情况。在

所以,不,在一系列相连的函数中使用**kwargs并不能提高效率。在

一个快速演示,演示传递给一系列函数的字典是不同的:

>>> def a(**kwargs):
...     print('a', id(kwargs))
...     b(**kwargs)
...
>>> def b(**kwargs):
...     print('b', id(kwargs))
...
>>> a(foo='bar')
a 4556474552
b 4557517304

如果字典是共享的,它们的id()值也将相同。在

如果要在函数之间传递共享状态,请显式地这样做。直接把字典传下去,例如:

^{pr2}$

坦白说,我真的很喜欢玛蒂恩的回答。为了按照我相信你的原意回答你的问题,你需要跳过Martijn所说的**

def a(some_dict):
    # do some operations on this dict
    b(some_dict)

def b(some_dict):
    # do some more operations on this dict
    c(some_dict)

def c(some_dict):
    # you know how this goes by know, don't you?

# Careful thing to note here: you do not need to reassign here,
# since each function are dealing with a reference to the same
# original object, there is no need to pass it back when we are
# done.

a(some_dict)

进一步说,这在我认为是工厂模式中非常常见

^{pr2}$

相关问题 更多 >