使用str.format()访问对象属性

42

我有一个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)

然而,语法是不正确的。这是可能的吗?

6个回答

68

您可以在格式字段内部使用 .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中的格式化字符串语法链接。

12
这个看起来更好: print '我的对象有字符串 a={obj.a}, b={obj.b}, c={obj.c}'.format(obj=obj) - Roman L
1
@RomanL - 该主题发布者不喜欢他目前的解决方案,因为它需要您在每个属性中都键入“obj”一次。我认为这种重复繁琐且不必要。但是正如您所说,这主要是偏好问题。:) - user2555451
8
也可以使用以下方法之一进行格式化:'{a} {b}'.format(**vars(obj))'{a} {b}'.format(**obj.__dict__) - igniteflow
@iCodez,您可以使用这个来访问类方法吗?还是只能访问类属性? - Halcyon Abraham Ramirez
1
@HalcyonAbrahamRamirez - 你可以访问方法,但是你将无法调用它们。相反,你会得到一个方法的字符串表示,例如:<bound method Class.method of <__main__.Class object at 0x0000000002CC27B8>>' - user2555451
显示剩余4条评论

21

我认为最好使用vars()将对象的属性作为dict访问,而不是使用__dict__

所以你可以这样做:

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

想要了解为什么vars()__dict__更可取,请参阅回答问题使用dict还是vars()?获得更多背景信息。


如果你定义了__slots__,那么就没有__dict__,这样vars将完全无法工作。 - Shiplu Mokaddim

7

正如@igniteflow在一个埋藏的评论中所写:

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

以我有限的Python了解: .__dict__ 是一个包含所有实例属性的字典,** 运算符基本上会解包它们并将它们作为键=值参数添加到方法中。


2
不错!使用 '' 是关键。在示例中包含 .dict 是不幸的,因为它使它看起来比实际复杂。例如:'我的对象有字符串 a={a},b={b}'。格式化({'a':'hi', 'b':'mom'}) - pythonjsgeo

2

为了完整起见,在 @igniteflow 和 @Christian 的基础上,您可以使用 % 字符串格式运算符并编写:

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

1
一些建议使用 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'

我认为最好坚持使用可靠的东西,并明确列出需要打印的内容。
如果您需要打印大量属性,则将这些值存储为属性可能不是最佳选择。

0

使用格式化字符串字面量:

>>> class A:
...     def __init__(self):
...             return
... 
>>> a = A
>>> a.value = 123
>>> f' a.value is: {a.value}'
' a.value is: 123

您可以直接从命名空间中的对象访问属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接