Python全局Summary类实例调用时file属性变为None的原因及解决
问题描述
我编写了一段Python代码,其中包含一个用于记录执行过程的summary类,代码如下:
#Summary.py class summary : def __init__(self): self.file = None def late_init(self, file_name): self.file = open(file_name, "w") self.create_file() def create_file(self): self.file.write("bla bla title") def write_info(self, info): self.file.write(date() + info) def finish(self): self.file.close()
在config.py中将mySummary声明为全局实例,方便各处调用:
#config.py global mySummary mySummary = summary()
主程序代码如下:
def create_working_directory(): os.mkdir("Output_file") mySummary.late_init("Output_file") # 此步骤原本预期可正常创建文件并写入基础信息 # main.py create_working_directory() work1() mySummary.write_info("Work1 done")
最后一行代码抛出AttributeError: 'NoneType' object has no attribute 'write'错误,排查发现调用write_info时mySummary.file从<class '_io.TextIOWrapper'>变成了<class 'NoneType'>,请问该现象的原因是什么?如何修复?
原因分析
- 传入目录而非文件名导致文件对象初始化失败:
late_init方法里传入的是目录名"Output_file",不是具体文件名。调用open()尝试打开目录作为文件时,操作系统会直接拒绝这个操作,触发IO异常。如果没有捕获异常,self.file会保持None状态,后续调用write_info自然报错。你之前觉得“正常创建文件”,大概率是之前测试时创建过同名文件,后续改成目录后未清理,导致当前运行时的异常被忽略或未触发,但实际文件对象并未正确初始化。 date()函数未导入:write_info里直接调用date(),但没有导入对应的模块,这会触发NameError,如果work1()里的异常处理逻辑影响了全局实例,也可能间接导致mySummary.file被重置为None。- 全局实例的引用冲突:如果不同模块导入
mySummary的方式错误,比如重复创建了summary实例,会导致实际使用的实例并非config.py中初始化的那个,新实例的file属性自然是None。
修复方案
- 修正文件路径,传入具体文件名:
late_init需要接收文件名而非目录,比如"Output_file/summary.log",同时可以先确保目录存在:
调用时修改为:import os class summary : # ... 其他方法 ... def late_init(self, file_name): # 自动创建文件所在目录 dir_path = os.path.dirname(file_name) if dir_path and not os.path.exists(dir_path): os.makedirs(dir_path) self.file = open(file_name, "w") self.create_file()mySummary.late_init("Output_file/summary.log") - 补全
date()函数的导入:在Summary.py开头添加导入,或者改用更清晰的时间格式:from datetime import datetime def write_info(self, info): self.file.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} {info}\n") - 确保全局实例的正确引用:所有需要使用
mySummary的模块,统一从config.py导入,避免重复创建实例。比如在main.py开头添加:from config import mySummary - 添加异常保护,避免文件对象失效:在文件操作方法中添加判断,确保文件对象存在时再执行操作:
def write_info(self, info): if self.file is not None: from datetime import datetime self.file.write(f"{datetime.now()} {info}\n") def finish(self): if self.file is not None: self.file.close() self.file = None
内容的提问来源于stack exchange,提问作者Daniel Bar
相关产品推荐
相关产品推荐

