2015-06-23 4 views
3

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

TypeError: print_smt() takes 1 positional argument but 2 were given

, потому что он проходит пустой словарь функции, я полагаю.

Как я могу решить эту проблему? Я вынужден использовать оператор if для вызова функции с параметрами или без них, или есть лучший способ решить проблему?

class Bar(object): 
    def print_smt(self, text): 
    print(text) 

class Foo(object): 
    def print_smt(self): 
    print("Nothing") 

def test(obj, **p2): 
    obj.print_smt(p2) 


bar = Bar() 
test(bar, text='print this') 

foo = Foo() 
test(foo) # This one breaks! 
+2

Это кажется плохим выбором дизайна для начала; мы могли бы дать вам лучшее решение вашей проблемы, если вы подробно расскажете о том, что делают ваши два класса, и почему вы чувствуете необходимость давать им разные методы с тем же именем. Я подозреваю, что аргумент по умолчанию поможет вам, но я не могу сказать точно из этого тонкого примера. – Air

+1

Если вы _want_ для того, чтобы сделать pass-a-notempty-dict вещь, кстати, это возможно без двух отдельных вызовов (хотя я бы сказал, что подход с двумя вызовами более читабельен и, следовательно, предпочтительнее): 'obj.print_smt (* ([p2], если p2 else [])). Опять же, если бы было определено, насколько это реально, что было вашим реальным вопросом, в этом обсуждении не было бы необходимости в kwargs. –

ответ

6

Когда вы звоните:

def test(obj, **p2): 
    obj.print_smt(p2) 

... вы передаете словарь в print_smt(). Даже если это пустой словарь, он по-прежнему является словарем, и вы не можете передавать словарь в качестве аргумента в то, что не принимает аргументов.


Если вы хотите, чтобы пройти через именованные аргументы в качестве ключевых аргументов, а не в качестве одного позиционного аргумента со словарем, то сделайте так:

def test(obj, **p2): 
    obj.print_smt(**p2) 
2

Вы должны распаковать kwargs перед передачей его функции print_smt. Это работает:

def test(obj, **p2): 
    obj.print_smt(**p2) 
Смежные вопросы