Python __str__和列表

问题:Python __str__和列表

在Java中,如果我调用List.toString(),它将自动在List内的每个对象上调用toString()方法。例如,如果我的列表包含对象o1,o2和o3,则list.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自动为列表中的每个元素(或dict)调用__str__?

In Java, if I call List.toString(), it will automatically call the toString() method on each object inside the List. For example, if my list contains objects o1, o2, and o3, list.toString() would look something like this:

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

Is there a way to get similar behavior in Python? I implemented a __str__() method in my class, but when I print out a list of objects, using:

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

it looks something like this:

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

how can I get python to call my __str__ automatically for each element inside the list (or dict for that matter)?


回答 0

在python列表上调用string会调用__repr__内部每个元素的方法。对于一些项目,__str__并且__repr__是相同的。如果您想要这种行为,请执行以下操作:

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

Calling string on a python list calls the __repr__ method on each element inside. For some items, __str__ and __repr__ are the same. If you want that behavior, do:

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

回答 1

您可以使用列表推导自动生成一个带有每个str()项目的新列表:

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

You can use a list comprehension to generate a new list with each item str()’d automatically:

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

回答 2

您可以做两个简单的事情,使用map函数或理解。

但这会为您提供字符串列表,而不是字符串。因此,您还必须将字符串连接在一起。

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

要么

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

然后,您可以打印此复合字符串对象。

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

Two easy things you can do, use the map function or use a comprehension.

But that gets you a list of strings, not a string. So you also have to join the strings together.

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

or

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

Then you can print this composite string object.

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

回答 3

根据您要使用该输出的目的,也许__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()

Depending on what you want to use that output for, perhaps __repr__ might be more appropriate:

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()

回答 4

我同意先前关于使用列表推导来执行此操作的答案,但是如果您的想法浮出水面,则可以将其隐藏在函数后面。

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()包含在列表中的所有内容。

I agree with the previous answer about using list comprehensions to do this, but you could certainly hide that behind a function, if that’s what floats your boat.

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]

Just for fun, I made list_str() recursively str() everything contained in the list.


回答 5

像这样吗

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

Something like this?

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

回答 6

这样就足够了。

在打印列表以及其他容器类时,将使用来打印包含的元素__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__为一个对象实现了if ,__repr__则not 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 

This should suffice.

When printing lists as well as other container classes, the contained elements will be printed using __repr__, because __repr__ is meant to be used for internal object representation. If we call: help(object.__repr__) it will tell us:

Help on wrapper_descriptor:

__repr__(self, /)
    Return repr(self).

And if we call help(repr) it will output:

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.

If __str__ is implemented for an object and __repr__ is not repr(obj) will output the default output, just like print(obj) when non of these are implemented.

So the only way is to implement __repr__ for your class. One possible way to do that is this:

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 

回答 7

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

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

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

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

如果您覆盖此__repr__功能,则可以像以前一样使用打印方法:

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]”作为输出。

The output you’re getting is just the object’s module name, class name, and then the memory address in hexadecimal as the the __repr__ function is not overridden.

__str__ is used for the string representation of an object when using print. But since you are printing a list of objects, and not iterating over the list to call the str method for each item it prints out the objects representation.

To have the __str__ function invoked you’d need to do something like this:

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

If you override the __repr__ function you can use the print method like you were before:

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

Then you’ll get “my list is [1, 2, 3]” as your output.