Форматирование ключей dict: AttributeError: объект' dict 'не имеет атрибута' keys()'
Как правильно форматировать ключи dict в строке?
Когда я делаю это:
>>> foo = {'one key': 'one value', 'second key': 'second value'}
>>> "In the middle of a string: {foo.keys()}".format(**locals())
Чего я ожидаю:
"In the middle of a string: ['one key', 'second key']"
Что я получаю:
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
"In the middle of a string: {foo.keys()}".format(**locals())
AttributeError: 'dict' object has no attribute 'keys()'
Но, как вы можете видеть, у моего диктатора есть ключи:
>>> foo.keys()
['second key', 'one key']
4 ответа:
Нельзя вызывать методы в заполнителях. Вы можете получить доступ к свойствам и атрибутам и даже индексировать значение - но вы не можете вызвать методы:
class Fun(object): def __init__(self, vals): self.vals = vals @property def keys_prop(self): return list(self.vals.keys()) def keys_meth(self): return list(self.vals.keys())
Пример с методом (ошибка):
>>> foo = Fun({'one key': 'one value', 'second key': 'second value'}) >>> "In the middle of a string: {foo.keys_meth()}".format(foo=foo) AttributeError: 'Fun' object has no attribute 'keys_meth()'
Пример со свойством (рабочим):
>>> foo = Fun({'one key': 'one value', 'second key': 'second value'}) >>> "In the middle of a string: {foo.keys_prop}".format(foo=foo) "In the middle of a string: ['one key', 'second key']"
Синтаксис форматирования дает понять, что вы можете получить доступ только к атрибутам (a la
getattr
) или индексам (a la__getitem__
) заполнителей (взятых из "синтаксис строки формата"):За именем arg_name можно следовать любым числом индексных или атрибутивных выражений. Выражение вида
'.name'
выбирает именованный атрибут с помощьюgetattr()
, в то время как выражение вида'[index]'
выполняет поиск индекса с помощью__getitem__()
.
С Python 3.6 вы можете легко сделать это с f-строками, вам даже не нужно передавать
locals
:>>> foo = {'one key': 'one value', 'second key': 'second value'} >>> f"In the middle of a string: {foo.keys()}" "In the middle of a string: dict_keys(['one key', 'second key'])" >>> foo = {'one key': 'one value', 'second key': 'second value'} >>> f"In the middle of a string: {list(foo.keys())}" "In the middle of a string: ['one key', 'second key']"
Как было сказано другими выше, вы не можете сделать это так, как вы бы предпочли, вот дополнительная информация, чтобы следовать python string format вызова функции