【问题标题】:Use str.format() to access object attributes使用 str.format() 访问对象属性
【发布时间】:2015-01-03 16:38:59
【问题描述】:

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

但是,语法不正确。这可能吗?

【问题讨论】:

    标签: python string string-formatting


    【解决方案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'
    

    我认为最好坚持使用可靠的内容并明确列出您需要打印的内容。

    如果您需要打印大量属性,那么将这些值存储为属性可能不是最好的主意。

    【讨论】:

      【解决方案2】:

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

      所以你可以这样做:

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

      有关为什么vars() 优于__dict__ 的更多背景信息,请参阅问题Use dict or vars()? 的答案。

      【讨论】:

      • 如果你定义了__slots__,就没有__dict__,那么vars就根本不起作用。
      【解决方案3】:

      正如@igniteflow 在隐藏评论中所写:

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

      由于我对 python 的理解有限:.__dict__ 是一个包含所有实例属性的字典,** 运算符基本上将它们解包并将它们作为 key=value args 添加到方法中

      【讨论】:

      • 不错!使用'**'是关键。在示例中包含 .__dict__ 是不幸的,因为它使它看起来比实际更复杂。例如'我的对象有字符串 a={a}, b={b}'.format(**{'a':'hi', 'b':'mom'})
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        您可以在格式字段本身内使用.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

        【讨论】:

        • 这对我来说看起来更好:print 'My object has strings a={obj.a}, b={obj.b}, c={obj.c}'.format(obj=obj)
        • 太棒了,谢谢。做“0”。 (例如0.a)表示传递给格式的项目的索引?
        • @RomanL - OP 不喜欢他当前的解决方案,因为它要求您为每个属性键入一次 obj。多次写obj 是乏味且不必要的IMO。但是,正如你所说,这主要是一个偏好问题。 :)
        • 还有'{a} {b}'.format(**vars(obj))'{a} {b}'.format(**obj.__dict__)
        • @HalcyonAbrahamRamirez - 您可以访问方法,是的,但您将无法调用它们。相反,您将获得该方法的字符串表示形式,例如:&lt;bound method Class.method of &lt;__main__.Class object at 0x0000000002CC27B8&gt;&gt;'.
        猜你喜欢
        • 1970-01-01
        • 2021-03-05
        • 2015-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多