Упаковать аргументы функции в словарь-напротив * * kwargs


Я пытаюсь сделать что-то противоположное тому, что делают **кварги, и я не уверен, что это вообще возможно. Но зная Python это вероятно так :-) Я хочу, чтобы все атрибуты были четко разработаны в моем методе (для автоматического завершения и простоты использования), и я хочу захватить их все, как, скажем, словарь, и передать дальше.

class Foo(object):
   def __init__(self, a=1, b=2):
      inputs = grab_function_inputs_somehow()
      self.bar(**inputs)

   def bar(self, *args, **kwargs):
      pass

Нормальная вещь для so-это назначить каждому входу параметр объекта, но я не хочу делать это для всех классов. Я надеялся найти способ обернуть это в метод это можно унаследовать.

2 4

2 ответа:

Вы можете диктовать переменные с помощью locals () . Например:

class Foo(object):
    def __init__(self, a=1, b=2):    
        inputs = locals()
        del inputs['self'] # remove self variable
        print(inputs)


f = Foo() 

Результаты в распечатке:

{'b': 2, 'a': 1}

Это возможно, но требует небольшой настройки кода:

class Foo(object):
    def __init__(self, **inputs):
        # Have to set your defaults in here
        inputs['a'] = inputs.get('a', 1)
        inputs['b'] = inputs.get('b', 2)
        # Now the rest of your code, as you expected
        self.bar(**inputs)

    def bar(self, *args, **kwargs):
        print("bar got: %s" % kwargs)


# No arguments, use defaults
Foo()           # bar got: {'a': 1, 'b': 2}
# Arguments provided
Foo(a=3, b=4)   # bar got: {'a': 3, 'b': 4}
Таким образом, вместо предоставления аргументов по умолчанию в определении функции вы гарантируете, что ключи, которые вы ожидаете, существуют, либо с предоставленным аргументом, либо с параметрами по умолчанию, которые вы передаете в качестве второго аргумента <dict>.get().

Править __init__ также может быть записано как:

def __init__(self, **inputs):
    # Have to set your defaults in here
    if 'a' not in inputs: inputs['a'] = 1
    if 'b' not in inputs: inputs['b'] = 2
    # Now the rest of your code, as you expected
    self.bar(**inputs)

# or

def __init__(self, **inputs):
    # Have to set your defaults in here
    args = {'a': 1, 'b':2}
    args.update(inputs)
    # Now the rest of your code, as you expected
    self.bar(**args)

В зависимости от количества аргументов по умолчанию, последний вариант может быть предпочтительным.