当我试图打印一个类的实例时,我得到了这样的输出:

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

我如何使它打印将显示自定义的东西(例如,包括属性值的东西)?也就是说,我如何才能定义类的实例在打印时将如何出现(他们的字符串表示)?


参见如何为类本身(而不是类的实例)选择自定义字符串表示?如果你想为类本身定义行为(在这种情况下,print(Test)显示一些自定义的东西,而不是<class __main__。测试>或类似)。(事实上,技术本质上是相同的,但应用起来更棘手。)


当前回答

尽管这是一篇较老的文章,但在数据类中也引入了一个非常方便的方法(从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')

如果你想隐藏某个属性不被输出,你可以将字段装饰器参数repr设置为False:

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

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

其他回答

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

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

你只需要确保在你的课结束时有括号,例如:

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

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

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

__repr__和__str__已经在许多答案中提到。我只是想补充一点,如果你懒得把这些神奇的函数添加到你的类中,你可以使用objprint。一个简单的装饰器@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
  >
>

一个通用的方法,可以应用到任何类没有特定的格式,可以这样做:

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.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')

如果你想隐藏某个属性不被输出,你可以将字段装饰器参数repr设置为False:

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

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