You need to enable JavaScript to run this app. Python为何print输出eval(repr)生成的对象时调用__str__而非__repr__?
优惠活动
大模型
产品
解决方案
定价
更多

Python为何print输出eval(repr)生成的对象时调用__str__而非__repr__?

问题核心逻辑拆解

触发结果的本质原因

这个现象完全是由print函数的固定调用逻辑导致的,和eval、repr的组合过程没有关系。
print函数在处理传入的对象时,会严格按照固定优先级获取用于输出的字符串:

  • 第一优先级:调用对象的__str__魔术方法,拿到面向用户的可读字符串
  • 仅当对象没有实现__str__方法时,才会回退调用对象的__repr__魔术方法获取输出内容

代码执行链路逐段对应

结合给出的测试代码,每一步的执行逻辑可以完全匹配实际运行结果:

  1. 执行print(str(x))时,显式调用内置str()方法,触发x对象的__str__,输出友好格式的Name: Marvin, Build Year: 1979
  2. 执行print(x)时,走print的默认对象转字符串逻辑,同样触发__str__,输出和上一步完全一致的内容
  3. 执行print(repr(x))时,显式调用内置repr()方法,触发x对象的__repr__,拿到可用于重建对象的字符串Robot('Marvin', 1979),再把这个字符串本身打印出来
  4. 执行new = eval(repr(x))时,把上一步拿到的可重建字符串作为Python代码执行,重新生成一个属性和x完全一致的Robot类实例。这个new对象是完全正常的类实例,和直接通过构造方法生成的对象没有任何区别,不存在特殊的“repr生成对象”的特殊属性
  5. 执行print(new)时,走print的默认对象转字符串逻辑,优先触发new对象的__str__,自然输出友好格式的字符串,不会调用__repr__

常见认知偏差澄清

这个场景下的认知混淆,本质是把两个完全独立的流程错误绑定在了一起:误以为eval(repr(x))生成的对象,在打印时会和生成它的repr字符串有特殊关联。实际上当new实例生成完成后,后续对它的所有操作都和之前的repr、eval流程没有任何绑定关系。

可以做个简单的对照验证:把Robot类里的__str__方法删除,再执行同样的print(new),此时由于类没有实现__str__,print会回退调用__repr__,输出Robot('Marvin', 1979)的内容,刚好反向印证print的优先级规则。


内容的提问来源于stack exchange,提问作者Lucky1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 17:27:05