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

当我尝试print一个类的实例时,我得到一个这样的输出:

>>> class Test():
...     def __init__(self):
...         self.a = 'foo'
...
>>> print(Test())
<__main__.Test object at 0x7fc9a9e36d60>

如何定义类及其实例的印刷行为(或字符串表示)?例如,参考上面的代码,如何修改Test类以使print ing实例显示a值?

1207292 次浏览
>>> 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()函数(或当您使用交互式提示符查看它时)时发生的情况。

如果没有给出__str__方法,Python将改为打印__repr__的结果。如果您定义了__str__但没有定义__repr__,Python将使用您在上面看到的__repr__,但仍然使用__str__进行打印。

正如Chris Lutz解释的那样,这是由类中的__repr__方法定义的。

repr()的留档:

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

给定以下类测试:

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


def __repr__(self):
return f"<Test a:{self.a} b:{self.b}>"


def __str__(self):
return f"From str method of Test: a is {self.a}, b is {self.b}"

…它将在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):
cls = self.__class__
return f"<{cls.__module_}.{cls.__qualname__} object at {id(self)}>"

为了给@dbr的回答加上我的两分钱,下面是一个如何实现他引用的官方留档中这句话的例子:

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

给定这个类定义:

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

但是,正如我在上次评论中所说:更多信息只是这里

您需要使用__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

这个帖子里已经有很多答案了,但没有一个对我有特别的帮助,我必须自己解决,所以我希望这个答案能提供更多的信息。

您只需要确保在课程末尾有括号,例如:

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

为了打印我的氢类,我使用了以下内容:

print(Hydrogen())

请注意,如果没有氢结尾的括号,这将不起作用。它们是必要的。

希望这有帮助,让我知道如果你有更多的问题。

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

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}

对于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)

@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__)))

如果你处于@陈志立这样的情况,你可以尝试:

print(a.__dict__)

它违背了我认为好的风格,但如果你只是想调试,那么它应该做你想要的。

很简单。在打印中,执行:

print(foobar.__dict__)

只要构造函数是

__init__

__repr____str__已经在很多答案中提到了。我只想补充一点,如果你懒得给你的类添加这些神奇的函数,你可以使用对象打印。一个简单的装饰器@add_objprint将帮助你将__str__方法添加到你的类中,你可以使用print作为实例。当然,如果你愿意,你也可以使用库中的objprint函数以人类可读的格式打印任何任意对象。

from objprint import add_objprint


class Position:
def __init__(self, x, y):
self.x = x
self.y = y


@add_objprint
class Player:
def __init__(self):
self.name = "Alice"
self.age = 18
self.items = ["axe", "armor"]
self.coins = {"gold": 1, "silver": 33, "bronze": 57}
self.position = Position(3, 5)


print(Player())

输出就像

<Player
.name = 'Alice',
.age = 18,
.items = ['axe', 'armor'],
.coins = {'gold': 1, 'silver': 33, 'bronze': 57},
.position = <Position
.x = 3,
.y = 5
>
>

尽管这是一篇较旧的帖子,但在数据类中也引入了一个非常方便的方法(从Python 3.7开始)。除了__eq____hash__等其他特殊函数外,它还为类属性提供了__repr__函数。你的例子是:

from dataclasses import dataclass, field
@dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar")


t = Test()
print(t)
# prints Test(a='foo', b='bar')

如果你想隐藏某个属性不被输出,你可以设置领域装饰器参数reprFalse

@dataclass
class Test:
a: str = field(default="foo")
b: str = field(default="bar", repr=False)


t = Test()
print(t)
# prints Test(a='foo')