может ** kwargs расширяться в явно названные аргументы в вызове метода

Я довольно долго искал это, поэтому, пожалуйста, извините, если я что-то упустил.

Обычно я хочу, чтобы методы в моей системе имели только явные именованные аргументы (кроме себя, конечно), например:

# 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 не отображаются в названные аргументы в method_2, но если я сделаю это вместо этого в конце method_1:

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

тогда значения по умолчанию x и y из метода_1 переопределяют значения по умолчанию, выраженные в сигнатуре метода_2.

то, что я хочу, - это способ без размытия сигнатур методов путем принятия полностью открытого и неуказанного ** kwargs, чтобы сопоставить все, что может быть указано в вызове dict, в явные именованные параметры и не переопределять значения по умолчанию для других аргументов, которые не переданы диктат

Это возможно?

это для системы из сотен классов, и их интерфейсы должны быть очень хорошо определены, иначе это просто безумие. вот почему я не хочу передавать ** kwargs, кроме как в очень контролируемой манере, и я также хочу воспользоваться преимуществами именованных аргументов, значения по умолчанию которых указаны в сигнатуре метода. в противном случае, конечно, я мог бы иметь дело со значениями по умолчанию в теле метода:

if x is None:
    x = 5

это просто не так приятно ...


person Bruce    schedule 04.05.2016    source источник
comment
Можете ли вы предоставить минимальный воспроизводимый пример, демонстрирующий неправильное поведение? Я понимаю суть того, о чем вы спрашиваете, но не совсем уверен, что понимаю, что именно вы хотите.   -  person Steve Cohen    schedule 05.05.2016
comment
@steve: хммм, ты говоришь, что такое отображение должно иметь место? я постараюсь сделать лучший и исполняемый пример. до тех пор, полагаю, я как-то напортачил. вернусь ... спасибо.   -  person Bruce    schedule 05.05.2016
comment
вздох. Кажется, я здесь совершенно не прав. поведение, которое я видел, было моим собственным делом. в моей собственной очень скудной защите я задал этот же вопрос нашему очень хорошо осведомленному специалисту по питону, и он сказал, что это не сработает, если переданный ** kwargs отобразит свои аргументы в набор именованных аргументов в подписи вызываемого метода , но, когда я пытаюсь проверить это дальше, похоже, что он делает именно это. Я так счастлив по этому поводу, я перестану быть проигравшим. мои извинения за потраченное зря ваше время. если месть - это то, что вы хотите сейчас, просто знайте, что я зря потратил гораздо больше своего времени !! : -   -  person Bruce    schedule 05.05.2016
comment
как снять вопрос, чтобы не тратить зря время?   -  person Bruce    schedule 05.05.2016
comment
По крайней мере, теперь есть достойный пример для следующего парня. Я не уверен, что это должно исчезнуть. Также - остерегайтесь своего очень хорошо осведомленного питона. Я также должен упомянуть, что использование расширения magic ** kwargs может, эээ ... сбить с толку следующего человека. И чаще всего я сам себе следующий.   -  person Steve Cohen    schedule 05.05.2016
comment
спасибо за вашу помощь (и более того, понимание. ха!)   -  person Bruce    schedule 05.05.2016


Ответы (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

Именно этого и следовало ожидать.

person Steve Cohen    schedule 04.05.2016
comment
это показывает именно то поведение, которое я хотел, но не думал, что вижу. большое спасибо. - person Bruce; 06.05.2016