Дополнительные функции фильтра Python kwargs

#python #keyword-argument

#python #ключевое слово-аргумент

Вопрос:

У меня есть словарь, который я хочу передать в matplotlib для построения гистограммы, это упрощает его, но немного похоже на это:

 import matplotlib.pyplot as plt

#This works fine:
plt.bar(x=range(3),height=[300,128,581],width=0.8,align='edge')

#This also works fine:
mydict = {'x':range(3),'height':[300,128,581],'width':0.8,'align':'edge'}
plt.bar(**mydict)

#But adding in something extra to my dictionary which might be there for other reasons screws it up:
mydict = {'x':range(3),'height':[300,128,581],'width':0.8,'align':'edge','fruit':'bananas'}
plt.bar(**mydict)

#/usr/local/python3/lib/python3.6/site-packages/matplotlib/pyplot.py in bar(x, height, width, bottom, #align, data, **kwargs)
#   2432     return gca().bar(
#   2433         x, height, width=width, bottom=bottom, align=align,
#-> 2434         **({"data": data} if data is not None else {}), **kwargs)
#   2435 
#   2436 
 

Я осмотрелся и вижу, что я могу использовать inspect , чтобы получить подробную информацию о функции и аргументах. inspect.signature(plt.bar) дает:

<Подпись (x, высота, ширина = 0,8, снизу = Нет, *, выравнивание = ‘center’, данные = Нет, ** kwargs)>

Это полезно с точки зрения удаления из моего словаря вещей, которых нет в этом списке, но затем я знаю из документации, что существуют другие необязательные kwargs, такие как linewidth и log .

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

Комментарии:

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

2. @buran это то, о чем я думал, но ошибка атрибута, которую я получаю дальше в коде, такова 'Rectangle' object has no property 'fruit'

Ответ №1:

Может быть, что-то вроде этого

 import matplotlib.pyplot as plt

# #But adding in something extra to my dictionary which might be there for other reasons screws it up:
required = {'x':range(3),'height':[300,128,581]}
optional = {'width':0.8,'align':'edge','fruit':'bananas'}
mybar = plt.bar(**required)
for key, value in optional.items():
    try:
        setattr(mybar, key, value)
    except AttributeError:
        pass
plt.show()
 

Комментарии:

1. Спасибо, я раньше не использовал setattr(), но это определенно кажется хорошим способом сделать это.

2. Это один из способов справиться с этим. ИМХО, это должно было быть обработано matplotlib , так что, возможно, есть какой-то вариант, о котором я не знаю. Было бы интересно, если кто-то предложит другое решение.