web-dev-qa-db-ja.com

str.format()を使用してオブジェクト属性にアクセスします

Python属性abcを持つオブジェクトがあります。

私はまだ古い文字列フォーマットを使用しているので、通常これらを手動で印刷します。

 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)

ただし、構文は正しくありません。これは可能ですか?

37
Adam Hughes

書式フィールド自体の中で.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の Format String Syntax に関するリファレンスを参照してください。

54
iCodez

___dict___を使用するのではなく、dictとしてオブジェクトの属性にアクセスするには、 vars() を使用する方が望ましいと思います。

だからあなたはこれを行うことができます:

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

vars()が___dict___よりも望ましい理由の詳細については、質問への回答を参照してください dictまたはvars()?

14
Geoffrey Hing

@igniteflowが埋もれたコメントで書いたように:

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

私の制限付きpython理解:.__dict__は、すべてのインスタンス属性と**演算子は基本的にそれらを展開し、key = value引数としてメソッドに追加します

5
Christian

完全を期すために、@ igniteflowと@Christianに基づいて、%文字列フォーマット演算子と書き込み:

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

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'

信頼性の高いものに固執し、印刷する必要があるものを明示的にリストすることが望ましいと思います。

大量の属性を印刷する必要がある場合、それらの値を属性として保存することは最良のアイデアではないかもしれません。

1
iggy