很多初学 Python 的小伙伴都遇到过这个尴尬问题:自己定义了一个类,实例化对象后直接 print() 打印,没有输出想要的内容,反而跳出一串莫名其妙的字符串,类似 <__main__.User object at 0x7f8b12345678>。
这到底是什么意思?为什么不能直接打印对象数据?怎么才能让打印对象输出自定义内容?今天这篇文章一次性讲透 Python 打印 object 的底层逻辑,看完彻底告别打印对象看不懂的问题!
一、先复现问题:默认打印对象的效果
我们先写一段最简单的自定义类代码,看看原生的打印效果:
# 自定义一个学生类
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
# 实例化对象
stu = Student("小明", 18, 95)
# 直接打印对象
print(stu)
输出结果:
<__main__.Student object at 0x7fa23d5c9820>
这串字符由三部分组成:
- __main__.Student:对象所属的类名,
__main__代表当前运行的脚本模块 - object:标识这是一个 Python 对象
- 0x7fa23d5c9820:对象在内存中的十六进制地址
简单来说:Python 默认不知道你想展示对象的哪个数据,所以只能打印对象的身份信息(类+内存地址)。
二、底层原理:Python 打印对象的执行逻辑
在 Python 中,所有类都默认继承顶层父类 object,而 object 自带两个核心方法,控制着对象的打印和展示效果:__str__ 和 __repr__。
当我们执行 print(对象) 时,Python 会优先执行这套逻辑:
- 优先调用对象的 __str__() 方法,获取字符串结果并打印;
- 如果没有定义
__str__(),则调用 __repr__() 方法; - 如果两个方法都没重写,就会调用
object父类的默认方法,输出我们看到的内存地址格式字符串。
这就是默认打印结果晦涩难懂的根本原因:父类的默认方法只输出对象身份,不输出自定义属性。
三、自定义打印:重写 __str__ 方法(日常首选)
__str__() 是给用户看的友好字符串,也是日常打印对象最常用的重写方法,优先级最高。我们只需要在类中重写这个方法,返回自定义的展示字符串,就能实现优雅打印。
改造上面的学生类:
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
# 重写__str__方法,自定义打印格式
def __str__(self):
# 返回想要展示的对象信息
return f"学生信息:姓名={self.name},年龄={self.age},分数={self.score}"
stu = Student("小明", 18, 95)
print(stu)
输出结果(清晰易懂):
学生信息:姓名=小明,年龄=18,分数=95
✅ 核心规则:__str__()必须返回字符串类型,不能直接 print,否则会报错。
四、进阶补充:重写 __repr__ 方法(开发调试首选)
很多小伙伴会疑惑两个方法的区别,这里直白区分:
- __str__:面向普通用户,追求简洁易懂,用于日常打印输出;
- __repr__:面向开发者,追求精准、完整,用于调试、日志、交互式终端展示。
如果只定义 __repr__,不定义 __str__,print 对象时会自动调用 __repr__。开发中建议 优先重写 __repr__,兼容性更强。
示例代码:
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
# 调试风格的对象展示
def __repr__(self):
return f"Student(name='{self.name}', age={self.age}, score={self.score})"
stu = Student("小明", 18, 95)
print(stu)
# 终端直接输入对象回车,也会触发__repr__
stu
输出结果:
Student(name='小明', age=18, score=95)
五、懒人技巧:一键打印对象所有属性
如果对象属性很多,一个个拼接字符串太麻烦,推荐两个懒人通用方法,无需手动拼接:
方法1:使用 __dict__ 打印所有属性
Python 对象的 __dict__ 属性会存储对象所有自定义属性和值,直接打印即可:
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
stu = Student("小明", 18, 95)
print(stu.__dict__)
输出:{'name': '小明', 'age': 18, 'score': 95}
方法2:封装通用打印方法(所有类通用)
def print_obj(obj):
print(f"【{type(obj).__name__}对象信息】")
for k, v in obj.__dict__.items():
print(f"{k}: {v}")
# 调用
print_obj(stu)
六、高频面试/笔试考点总结
- 默认打印对象输出
xxx object at 0x...的原因:未重写__str__和__repr__,调用了 object 父类默认方法; - print(对象) 优先调用
__str__,次选__repr__; __str__面向用户,__repr__面向开发者调试;- 两个方法都必须返回字符串,不能直接打印。
七、最后总结
Python 打印对象看不懂,根本不是代码 bug,只是缺少自定义的对象展示规则。
- 日常业务输出:重写__str__,简洁友好;
- 开发调试排查:重写 __repr__,精准规范;
- 快速查看属性:直接使用 __dict__,高效便捷。
掌握这几个用法,彻底解决 Python 对象打印晦涩的问题,代码可读性直接拉满!