【问题标题】:Python __str__ and listsPython __str__ 和列表
【发布时间】:2009-04-07 21:57:59
【问题描述】:

在Java中,如果我调用List.toString(),它会自动调用List内每个对象的toString()方法。例如,如果我的列表包含对象o1o2o3list.toString() 将如下所示:

"[" + o1.toString() + ", " + o2.toString() + ", " + o3.toString() + "]"

有没有办法在 Python 中获得类似的行为?我在课堂上实现了一个__str__() 方法,但是当我打印出一个对象列表时,使用:

print 'my list is %s'%(list)

看起来像这样:

[<__main__.cell instance at 0x2a955e95f0>, <__main__.cell instance at 0x2a955e9638>, <__main__.cell instance at 0x2a955e9680>]

如何让 python 为列表中的每个元素自动调用我的 __str__()(或 dict )?

【问题讨论】:

标签: python


【解决方案1】:

在 python 列表上调用字符串会在其中的每个元素上调用 __repr__ 方法。对于某些项目,__str____repr__ 是相同的。如果您想要这种行为,请执行以下操作:

def __str__(self):
    ...
def __repr__(self):
    return self.__str__()

【讨论】:

  • __repr__ 识别__str__ 通常与Python data model 不一致,所以@daniel-lew 提出的列表推导方案更pythonic。
  • 无参数。我按要求回答了这个问题,这通常是 python 新手想如何思考问题的方式,但这并不意味着这是最好的回答方式。
  • Python 应该与其自己的数据模型保持一致,并对所有基元和聚合执行相同的操作。
  • 我认为 python 列表的默认行为是完全错误的。我希望列表中的str() 为里面的每个单独元素返回str()
【解决方案2】:

您可以使用list comprehension 生成一个新列表,其中每个项目都会自动为 str():

print([str(item) for item in mylist])

【讨论】:

  • 或者只是print(map(str, mylist)) - 它有点短
  • 一个问题是如果 mylist 中的项目也可能是一个列表
  • @anula print(map(str, mylist)) 给出&lt;map object at 0x000001A888E94A60&gt;。你必须print(list(map(str, mylist)))
【解决方案3】:

您可以做两件简单的事情,使用 map 函数或使用推导式。

但这会给你一个字符串列表,而不是字符串。因此,您还必须将这些字符串连接在一起。

s= ",".join( map( str, myList ) )

s= ",".join( [ str(element) for element in myList ] )

然后就可以打印这个复合字符串对象了。

print 'my list is %s'%( s )

【讨论】:

    【解决方案4】:

    根据您想将该输出用于什么目的,__repr__ 可能更合适:

    import unittest
    
    class A(object):
        def __init__(self, val):
            self.val = val
    
        def __repr__(self):
            return repr(self.val)
    
    class Test(unittest.TestCase):
        def testMain(self):
            l = [A('a'), A('b')]
            self.assertEqual(repr(l), "['a', 'b']")
    
    if __name__ == '__main__':
        unittest.main()
    

    【讨论】:

      【解决方案5】:

      我同意之前关于使用列表推导来执行此操作的答案,但您当然可以将其隐藏在函数后面,如果那是您的船。

      def is_list(value):
          if type(value) in (list, tuple): return True
          return False
      
      def list_str(value):
          if not is_list(value): return str(value)
          return [list_str(v) for v in value]
      

      只是为了好玩,我递归地创建了 list_str() str() 列表中包含的所有内容。

      【讨论】:

      • +1 这在分别实现__str____repr__ 时很有用
      【解决方案6】:

      这样的?

      a = [1, 2 ,3]
      [str(x) for x in a]
      # ['1', '2', '3']
      

      【讨论】:

        【解决方案7】:

        这应该足够了。

        当打印列表以及其他容器类时,包含的元素将使用__repr__ 打印,因为__repr__ 旨在用于内部对象表示。 如果我们打电话给:help(object.__repr__),它会告诉我们:

        Help on wrapper_descriptor:
        
        __repr__(self, /)
            Return repr(self).
        

        如果我们调用help(repr),它将输出:

        Help on built-in function repr in module builtins:
        
        repr(obj, /)
            Return the canonical string representation of the object.
        
            For many object types, including most builtins, eval(repr(obj)) == obj.
        

        如果为对象实现了__str____repr__ 不是repr(obj) 将输出默认输出,就像print(obj) 未实现这些时一样。

        所以唯一的方法是为你的班级实现__repr__。一种可能的方法是:

        class C:           
            def __str__(self):
                return str(f"{self.__class__.__name__} class str ")
        
        C.__repr__=C.__str__       
        ci = C()    
        
        
        print(ci)       #C class str 
        print(str(ci))  #C class str 
        print(repr(ci)) #C class str 
        

        【讨论】:

          【解决方案8】:

          您得到的输出只是对象的模块名称、类名称,然后是十六进制的内存地址,因为 __repr__ 函数未被覆盖。

          __str__ 在使用 print 时用于对象的字符串表示。但是,由于您正在打印对象列表,而不是遍历列表来为每个项目调用 str 方法,因此它会打印出对象表示。

          要调用__str__ 函数,您需要执行以下操作:

          'my list is %s' % [str(x) for x in myList]
          

          如果你重写 __repr__ 函数,你可以像以前一样使用 print 方法:

          class cell:
              def __init__(self, id):
                  self.id = id
              def __str__(self):
                  return str(self.id) # Or whatever
              def __repr__(self):
                  return str(self) # function invoked when you try and print the whole list.
          
          myList = [cell(1), cell(2), cell(3)]
          'my list is %s' % myList
          

          然后你会得到“my list is [1, 2, 3]”作为你的输出。

          【讨论】:

          • 这个答案似乎在回答一个完全不相关的问题。你确定你把它放在了正确的地方吗?
          • yes Blckknght 这个我想给出答案的页面有一个从另一个帖子指向这个页面的链接。所以它引导我来到这里,我在这里回答,假设提出问题的人会再次来到这里看看我的回答..抱歉给您带来不便!!!
          • 如果另一个问题作为这个问题的副本被关闭,那么这里的 existing 答案应该已经解决了另一个问题。如果不是这种情况,那么您应该标记以重新打开该问题,而不是在此处发布难以理解的答案,这几乎肯定会被删除。现在,您可能有话要说,但这里的其他 8 个答案之一没有涵盖,但是您需要在此页面的上下文中使您的答案有意义,因为您正在回答这个问题。并且不要发布两个相同的答案!
          • 哦,虽然现在我再看一遍,似乎 @charliebeckwith 出于某种莫名其妙的原因将您的帖子编辑为完全不同的帖子,而不是发布他们自己的答案。这通常不是编辑的工作方式......
          • @blckknght 在我意识到答案有多么偏离之前,我开始编辑它。完全莫名其妙为什么我继续前进。
          猜你喜欢
          • 2020-09-23
          • 1970-01-01
          • 2015-05-08
          • 2015-03-31
          • 1970-01-01
          • 2021-09-11
          • 2012-09-09
          • 1970-01-01
          • 2010-11-21
          相关资源
          最近更新 更多