Подтвердить что ты не робот

Используйте str.format() для доступа к атрибутам объекта

У меня есть объект Python с атрибутами a, b, c.

Я все еще использую форматирование старой строки, поэтому обычно печатаю вручную:

 print 'My object has strings a=%s, b=%s, c=%s' % (obj.a, obj.b, obj.c)

В последнее время мои строки стали очень длинными, и я бы скорее смог просто передать объект в функцию формата строки, что-то вроде:

 print 'My object has strings a=%a, b=%b, c=%c'.format(obj)

Однако синтаксис неверен. Возможно ли это?

4b9b3361

Ответ 1

Вы можете использовать нотацию .attribute_name внутри самих полей формата:

print 'My object has strings a={0.a}, b={0.b}, c={0.c}'.format(obj)

Ниже приведена демонстрация:

>>> class Test(object):
...     def __init__(self, a, b, c):
...         self.a = a
...         self.b = b
...         self.c = c
...
>>> obj = Test(1, 2, 3)
>>> 'My object has strings a={0.a}, b={0.b}, c={0.c}'.format(obj)
'My object has strings a=1, b=2, c=3'
>>>

Обратите внимание, что при этом вам нужно указывать поля формата. Кроме того, как вы можете видеть, функция str.format имеет свои поля формата, обозначенные фигурными фигурными скобками {...}, а не знаком %.

Для получения дополнительной информации см. ссылку на Синтаксис строки форматирования на Python.

Ответ 2

Как @igniteflow написал в похожем комментарии:

'My object has strings a={a}, b={b}, c={c}'.format(**obj.__dict__)

С моим ограниченным пониманием python: .__dict__ - это dict со всеми атрибутами экземпляров, и оператор ** в основном распаковывает их и добавляет их как key = value args к методу

Ответ 3

Я думаю, что предпочтительнее использовать vars() для доступа к атрибутам объекта как dict, а не usng __dict__.

Итак, вы можете сделать это:

"My object has strings a={a}, b={b}, c={c}".format(**vars(obj))

Для получения дополнительной информации о том, почему vars() предпочтительнее __dict__, см. ответ на вопрос Использовать dict или vars()?.

Ответ 4

Для полноты, основываясь на @igniteflow и @Christian, вы можете использовать оператор формата строки % и написать:

'My object has strings a=%(a)s, b=%(b)s, c=%(c)s' % obj.__dict__

Ответ 5

Некоторые из предложенных ответов, которые полагаются на vars(...), не работают с неизменяемыми объектами:

>>> class foo(object):
...   __slots__ = ()
...   def __init__(self):
...     self.x = 1
...
>>> vars(foo())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
AttributeError: 'foo' object has no attribute 'x'

Я думаю, что предпочтительнее придерживаться чего-то надежного и явно перечислять то, что вам нужно печатать.

Если вам нужно напечатать тонну атрибутов, то сохранение этих значений в качестве атрибутов может быть не лучшей идеей.