如何使用print()打印类的实例?

问题:如何使用print()打印类的实例?

我正在学习Python中的绳索。当我尝试Foobar使用该print()函数打印类的对象时,得到如下输出:

<__main__.Foobar instance at 0x7ff2a18c>

有没有办法设置及其对象打印行为(或字符串表示形式)?例如,当我调用类对象时,我想以某种格式打印其数据成员。如何在Python中实现?print()

如果您熟悉C ++类,则可以通过为类ostream添加friend ostream& operator << (ostream&, const Foobar&)方法来实现上述目的。

I am learning the ropes in Python. When I try to print an object of class Foobar using the print() function, I get an output like this:

<__main__.Foobar instance at 0x7ff2a18c>

Is there a way I can set the printing behaviour (or the string representation) of a class and its objects? For instance, when I call print() on a class object, I would like to print its data members in a certain format. How to achieve this in Python?

If you are familiar with C++ classes, the above can be achieved for the standard ostream by adding a friend ostream& operator << (ostream&, const Foobar&) method for the class.


回答 0

>>> class Test:
...     def __repr__(self):
...         return "Test()"
...     def __str__(self):
...         return "member of Test"
... 
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test

__str__方法是在打印时发生的事情,该__repr__方法是在使用repr()功能时(或在交互式提示下查看它时)发生的事情。如果这不是最Python的方法,我深表歉意,因为我也在学习-但这确实可行。

如果未提供任何__str__方法,Python将__repr__改为打印结果。如果定义__str__但没有__repr__,Python将使用你所看到的上面的__repr__,但仍使用__str__打印。

>>> class Test:
...     def __repr__(self):
...         return "Test()"
...     def __str__(self):
...         return "member of Test"
... 
>>> t = Test()
>>> t
Test()
>>> print(t)
member of Test

The __str__ method is what happens when you print it, and the __repr__ method is what happens when you use the repr() function (or when you look at it with the interactive prompt). If this isn’t the most Pythonic method, I apologize, because I’m still learning too – but it works.

If no __str__ method is given, Python will print the result of __repr__ instead. If you define __str__ but not __repr__, Python will use what you see above as the __repr__, but still use __str__ for printing.


回答 1

正如Chris Lutz所提到的,这是由__repr__您的类中的方法定义的。

从以下文档中repr()

对于许多类型,此函数会尝试返回一个字符串,该字符串将在传递给时产生一个具有相同值的对象eval(),否则表示形式是一个用尖括号括起来的字符串,其中包含对象类型的名称以及其他信息通常包括对象的名称和地址。类可以通过定义__repr__()方法来控制此函数为其实例返回的内容。

给定以下类Test:

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return "<Test a:%s b:%s>" % (self.a, self.b)

    def __str__(self):
        return "From str method of Test: a is %s, b is %s" % (self.a, self.b)

..it在Python Shell中的行为如下:

>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print repr(t)
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456

如果__str__未定义任何方法,则print(t)(或print(str(t)))将使用结果__repr__代替

如果__repr__未定义任何方法,则使用默认值,该默认值与..

def __repr__(self):
    return "<%s instance at %s>" % (self.__class__.__name__, id(self))

As Chris Lutz mentioned, this is defined by the __repr__ method in your class.

From the documentation of repr():

For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object. A class can control what this function returns for its instances by defining a __repr__() method.

Given the following class Test:

class Test:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def __repr__(self):
        return "<Test a:%s b:%s>" % (self.a, self.b)

    def __str__(self):
        return "From str method of Test: a is %s, b is %s" % (self.a, self.b)

..it will act the following way in the Python shell:

>>> t = Test(123, 456)
>>> t
<Test a:123 b:456>
>>> print repr(t)
<Test a:123 b:456>
>>> print(t)
From str method of Test: a is 123, b is 456
>>> print(str(t))
From str method of Test: a is 123, b is 456

If no __str__ method is defined, print(t) (or print(str(t))) will use the result of __repr__ instead

If no __repr__ method is defined then the default is used, which is pretty much equivalent to..

def __repr__(self):
    return "<%s instance at %s>" % (self.__class__.__name__, id(self))

回答 2

可以按以下方式完成可应用于任何类而无需特定格式的通用方法:

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

然后,

elem = Element('my_name', 'some_symbol', 3)
print(elem)

产生

__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}

A generic way that can be applied to any class without specific formatting could be done as follows:

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return str(self.__class__) + ": " + str(self.__dict__)

And then,

elem = Element('my_name', 'some_symbol', 3)
print(elem)

produces

__main__.Element: {'symbol': 'some_symbol', 'name': 'my_name', 'number': 3}

回答 3

如果遇到类似@Keith的情况,可以尝试:

print a.__dict__

它违背了我认为好的样式,但是如果您只是尝试调试,那么它应该可以做您想要的。

If you’re in a situation like @Keith you could try:

print a.__dict__

It goes against what I would consider good style but if you’re just trying to debug then it should do what you want.


回答 4

只是为了在@dbr的答案中加上我的两分钱,下面是他引用的官方文档中如何实现这句话的一个示例:

“ […返回一个字符串,当传递给eval()时,该字符串将产生具有相同值的对象,[…]”

给定此类定义:

class Test(object):
    def __init__(self, a, b):
        self._a = a
        self._b = b

    def __str__(self):
        return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)

    def __repr__(self):
        return 'Test("%s","%s")' % (self._a, self._b)

现在,很容易序列化Test类的实例:

x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print

y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print

因此,运行最后一段代码,我们将获得:

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

但是,正如我在最近的评论中所说:更多信息就在这里

Just to add my two cents to @dbr’s answer, following is an example of how to implement this sentence from the official documentation he’s cited:

“[…] to return a string that would yield an object with the same value when passed to eval(), […]”

Given this class definition:

class Test(object):
    def __init__(self, a, b):
        self._a = a
        self._b = b

    def __str__(self):
        return "An instance of class Test with state: a=%s b=%s" % (self._a, self._b)

    def __repr__(self):
        return 'Test("%s","%s")' % (self._a, self._b)

Now, is easy to serialize instance of Test class:

x = Test('hello', 'world')
print 'Human readable: ', str(x)
print 'Object representation: ', repr(x)
print

y = eval(repr(x))
print 'Human readable: ', str(y)
print 'Object representation: ', repr(y)
print

So, running last piece of code, we’ll get:

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

Human readable:  An instance of class Test with state: a=hello b=world
Object representation:  Test("hello","world")

But, as I said in my last comment: more info is just here!


回答 5

您需要使用__repr__。这是一个类似的标准功能__init__。例如:

class Foobar():
    """This will create Foobar type object."""

    def __init__(self):
        print "Foobar object is created."

    def __repr__(self):
        return "Type what do you want to see here."

a = Foobar()

print a

You need to use __repr__. This is a standard function like __init__. For example:

class Foobar():
    """This will create Foobar type object."""

    def __init__(self):
        print "Foobar object is created."

    def __repr__(self):
        return "Type what do you want to see here."

a = Foobar()

print a

回答 6

@ user394430的响应的更漂亮的版本

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return  str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))

elem = Element('my_name', 'some_symbol', 3)
print(elem)

产生视觉上漂亮的名称和值列表。

<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3

更好的版本(感谢Ruud)对项目进行排序:

def __str__(self):
    return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))

A prettier version of response by @user394430

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number

    def __str__(self):
        return  str(self.__class__) + '\n'+ '\n'.join(('{} = {}'.format(item, self.__dict__[item]) for item in self.__dict__))

elem = Element('my_name', 'some_symbol', 3)
print(elem)

Produces visually nice list of the names and values.

<class '__main__.Element'>
name = my_name
symbol = some_symbol
number = 3

An even fancier version (thanks Ruud) sorts the items:

def __str__(self):
    return  str(self.__class__) + '\n' + '\n'.join((str(item) + ' = ' + str(self.__dict__[item]) for item in sorted(self.__dict__)))

回答 7

对于Python 3:

如果特定格式不重要(例如,用于调试),则仅继承下面的Printable类。无需为每个对象编写代码。

灵感来自这个答案

class Printable:
    def __repr__(self):
        from pprint import pformat
        return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)

# Example Usage
class MyClass(Printable):
    pass

my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)

For Python 3:

If the specific format isn’t important (e.g. for debugging) just inherit from the Printable class below. No need to write code for every object.

Inspired by this answer

class Printable:
    def __repr__(self):
        from pprint import pformat
        return "<" + type(self).__name__ + "> " + pformat(vars(self), indent=4, width=1)

# Example Usage
class MyClass(Printable):
    pass

my_obj = MyClass()
my_obj.msg = "Hello"
my_obj.number = "46"
print(my_obj)

回答 8

这个线程中已经有很多答案,但是没有一个对我有特别的帮助,我必须自己解决这个问题,因此我希望这个答案能提供更多信息。

您只需要确保在类结束时有括号即可,例如:

print(class())

这是我正在从事的项目中的代码示例:

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number
    def __str__(self):
        return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number

class Hydrogen(Element):
    def __init__(self):
        super().__init__(name = "Hydrogen", symbol = "H", number = "1")

要打印我的Hydrogen类,我使用了以下内容:

print(Hydrogen())

请注意,如果没有氢末的括号,这将无法正常工作。它们是必需的。

希望这会有所帮助,如果您还有其他问题,请告诉我。

There are already a lot of answers in this thread but none of them particularly helped me, I had to work it out myself, so I hope this one is a little more informative.

You just have to make sure you have parentheses at the end of your class, e.g:

print(class())

Here’s an example of code from a project I was working on:

class Element:
    def __init__(self, name, symbol, number):
        self.name = name
        self.symbol = symbol
        self.number = number
    def __str__(self):
        return "{}: {}\nAtomic Number: {}\n".format(self.name, self.symbol, self.number

class Hydrogen(Element):
    def __init__(self):
        super().__init__(name = "Hydrogen", symbol = "H", number = "1")

To print my Hydrogen class, I used the following:

print(Hydrogen())

Please note, this will not work without the parentheses at the end of Hydrogen. They are necessary.

Hope this helps, let me know if you have anymore questions.