Python类中__repr__与__str__共存时的调用逻辑及Django场景疑问
关于Python中
__repr__/__str__及Django ValidationError的疑问解答 首先先解决你测试代码里的困惑:为什么print x调用了__repr__而不是__str__?
你写的测试类是Python2的旧式类(没有继承object):
class test(): # 旧式类,未继承object def __repr__(self): return 'repr called' def __str__(self): return 'str called'
在Python2中,旧式类的__str__方法不会被print语句优先调用,print会直接使用__repr__的返回值。如果把类改成新式类(继承object):
class test(object): # 新式类 def __repr__(self): return 'repr called' def __str__(self): return 'str called'
再执行print x,就会输出str called了——这才是__str__在新式类里的正常行为。
接下来聊聊Django ValidationError的__str__方法调用时机:
Django的ValidationError是新式类,它的__str__会在以下场景被触发:
- 显式调用
str()转换时:比如str(my_validation_error),会直接调用__str__方法,返回格式化后的错误内容。 - 使用
print()输出实例时:不管是Python2还是Python3,新式类的print操作都会优先调用__str__。 - 被自身的
__repr__间接触发:看你贴的代码,__repr__里写了return 'ValidationError(%s)' % self——这里的%s会自动调用str(self),也就是触发__str__。所以当你在交互式环境中直接输入实例名回车(会自动调用repr()),或者显式调用repr(my_validation_error)时,都会先执行__str__,再生成最终的__repr__返回值。 - 其他需要字符串转换的场景:比如把实例和字符串拼接(
"错误信息: " + my_validation_error)、将实例作为参数传给需要字符串输入的函数(比如logging.error(my_validation_error)),这些场景都会自动调用__str__。
另外补充下ValidationError这两个方法的设计逻辑:__str__负责把错误内容转换成易于阅读的结构化字符串(用repr(dict/list)保证格式清晰),而__repr__则生成一个能明确表示“这是一个ValidationError实例”的标识,同时复用__str__的结果来包含错误详情。
内容的提问来源于stack exchange,提问作者user1050619
相关产品推荐
相关产品推荐

