2016-12-06 2 views
5

Давайте следующий пример:Как передать байты в качестве ключа аргументов ключевого слова для функций?

def fun(**args): 
    print(str(args)) 

dic = {'name': 'Pulkit'} 
fun(**dic) 

Этот код работает отлично, и у меня есть следующий вывод:

{'name': 'Pulkit'} 

Теперь позволяет передавать значение как байт:

dic_vb = {'name': b'Pulkit'} 
fun(**dic_vb) 

Это также работает нормально и имеет следующий выход:

{'name': b'Pulkit'} 

Но все меняется, когда я пытаюсь иметь ключ в байтах:

dic_kb = {b'name': 'Pulkit'} 

Это приводит к TypeError говоря:

TypeError: fun() keywords must be strings 

Есть ли способ, мы можем передать байты в качестве аргументов ключевых слов. Я также проверил код CPython на repo, который имеет дело с ключевыми словами и кажется, что мы не можем пройти. Есть ли какое-либо обходное решение или мне нужно, чтобы убедиться, что unicodes переданы.

Я имею дело с кодовой базой, где у нас есть много таких экземпляров на Python 2, и ее нужно портировать на Python 3. Таким образом, возможен только преобразование всех аргументов ключевого слова в unicodes?

ответ

4

Нет, ключевые слова должны быть действительными идентификаторы, это та же самая причина, почему вы не можете предоставить словари, которые имеют номера, как ключи к функции ожидая **kwargs:

>>> dic = {1: 'Pulkit'} 
>>> fun(**dic) 
TypeErrorTraceback (most recent call last) 
<ipython-input-54-83c29ed0f08e> in <module>() 
     3 
     4 dic = {1: 'Pulkit'} 
----> 5 fun(**dic) 

TypeError: fun() keywords must be strings 

Это также то, что вы видели в источник, с отрицанием (!) от PyUnicode_Check, действующего в качестве исполнителя.

Требуется; вам нужно предоставить ключи, которые могут действовать как имена. Для того, чтобы увидеть, что и то, что не разрешено, просто пытаются присвоения его имени в интерактивном интерпретаторе и посмотреть, что заблуждается:

>>> b'my_list' = [...] # err 
>>> 23 = [21, 22]  # err 

Жизнеспособной (и единственный, если decode не допускается) вариант прохождения словаря как просто еще один аргумент, а затем доступ к значениям через обычные словарные поиски.

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

>>> dic = {b'name': 'Pulkit'} 
>>> fun(**{b.decode(): v for b, v in dic.items()}) 
Смежные вопросы