datetime表达式出现AttributeError:eval(repr(datetime对象))报错原因咨询
eval(repr(today))对datetime对象报错? 这是个很典型的命名空间与repr输出不匹配的问题,咱们一步步拆解来看:
1. 先搞懂repr(today)返回的内容
当你创建一个datetime对象并调用repr()时,它返回的字符串格式是这样的:
datetime.datetime(2024, 5, 20, 14, 30, 45, 123456)
这个字符串遵循**模块名.类名(参数)**的格式,它默认假设你的代码是通过import datetime导入整个模块的,这样datetime.datetime就能正确指向对应的类。
2. 你的导入方式导致了命名空间冲突
你的代码里用的是:
from datetime import datetime
这种导入方式是把datetime模块里的datetime类直接拉到当前命名空间里了——也就是说,在你的代码里,datetime这个名称对应的是datetime.datetime类本身,而不是datetime模块。
当eval()执行repr(today)生成的字符串时,它会尝试解析datetime.datetime:也就是想从名为datetime的模块里获取datetime类,但此时datetime已经是类了,不是模块,自然就会抛出AttributeError: type object 'datetime.datetime' has no attribute 'datetime'。
3. 两种可行的解决方法
方法一:导入整个datetime模块
把导入语句改成这样:
import datetime today = datetime.datetime.now() print(today == eval(repr(today))) # 现在会返回True
这样datetime指向的是模块,datetime.datetime就能正确找到对应的类,eval执行时就不会出错了。
方法二:给eval指定自定义命名空间
如果你坚持用from datetime import datetime的导入方式,可以在eval时手动映射命名空间:
from datetime import datetime today = datetime.now() print(today == eval(repr(today), {'datetime': datetime})) # 同样返回True
这里第二个参数给eval传入了一个字典,告诉它当遇到datetime时,直接使用当前命名空间里的datetime类,而不是去寻找同名模块。
总结
repr()的设计目标是尽可能返回能通过eval()重建对象的字符串,但它依赖于对象的完整模块路径。当你的导入方式改变了命名空间里的名称指向时,就会出现eval无法解析的情况。而像字符串这类内置类型,它们的repr输出不需要模块前缀,所以不会有这个问题。
内容的提问来源于stack exchange,提问作者Kunal

