can ** kwargs在方法调用中扩展为显式命名args

时间:2016-05-04 22:31:45

标签: python-3.x named-parameters kwargs

我搜索了很多,所以如果我错过了什么请原谅。

我一般希望系统中的方法只有明确的命名参数(当然不是self),如下所示:

# want an explicit parameter signature
def method_1(self, *, x = None, y = None):
    . . .
    # and here i want to pass x and/or y if they are not None
    possible_args = { }
    if x is not None:
        possible_args['x'] = x
    if y is not None:
        possible_args['y'] = y

    self.method_2(**possible_args)

# want an explicit parameter signature
def method_2(self, *, x = 1, y = None):
    . . .

不幸的是,x和/或y的值没有被映射到方法_2中的命名args,但是如果我在method_1的末尾执行此操作:

self.method_2(x = x, y = y)

然后,method_1中x和y的默认值将覆盖method_2签名中表示的默认值。

我想要的是一种方式,通过接受完全开放和未指定的** kwargs而没有迷惑方法签名,将调用dict中可能指定的任何内容映射到显式命名参数,而不覆盖其他args的默认值在通过的词典中。

这可能吗?

这适用于数百个类的系统,它们的接口需要很好地指定,否则这种方式就是疯狂。这就是为什么我不想以非常受控的方式传递** kwargs,我也想利用在方法签名中指定默认值的命名参数。否则,我可以处理方法体内的默认值,当然:

if x is None:
    x = 5

那不太好......

1 个答案:

答案 0 :(得分:1)

所以我给了它一个旋转,因为我迷失了问题所在。我仍然输了,但至少现在我可以告诉你一个MCVE:

#! /usr/bin/env python3

'''
A quick **kwargs demo
'''


def method_1(*, x_val=None, y_val=None):
    '''
    A demonstration with kwargs, that calls another with **kwargs.
    '''

    possible_args = {}
    if x_val is not None:
        possible_args['x_val'] = x_val
    if y_val is not None:
        possible_args['y_val'] = y_val
    method_2(**possible_args)


def method_2(*, x_val=1, y_val='y_from_2'):
    '''
    Print things for the demo.
    '''
    print('x_val = ', x_val, ', y_val = ', y_val)

method_1(x_val=17, y_val=7)
method_1(x_val=13)
method_1(y_val=5)
method_1()

产生输出:

x_val =  17 , y_val =  7
x_val =  13 , y_val =  y_from_2
x_val =  1 , y_val =  5
x_val =  1 , y_val =  y_from_2

这正是人们应该期待的。