导入自定义模块后scipy.io.loadmat报TypeError错误的解决方法
问题描述
- 现有Jupyter笔记本
main.ipynb和自定义模块data.py - 简化版
data.py导入scipy并调用scipy.io.loadmat加载.mat文件;main.ipynb先导入numpy、scipy、sys,第一个单元格成功调用scipy.io.loadmat,但导入data模块后,再次调用同一函数时抛出TypeError: 'NoneType' object is not callable错误 - 实际场景中
data.py包含load_matfiles(兼容scipy和mat73加载.mat文件)和load_data函数 - 环境:Python 3.12.4、Scipy 1.13.1,已尝试卸载重装Scipy、降级至1.11版本,问题仍存在
错误栈
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[4], line 1 ----> 1 mousedatatest = t.load_data("../datafiles/C57_913_Qiu/time_binned_DiscreteSpikes.mat") File ~/code/bayesian_decoder/scripts/testing.py:5, in load_data(filepath) 3 def load_data(filepath): 4 print(f"Loading data from: {filepath}") ----> 5 return scipy.io.loadmat(filepath) File /Applications/anaconda3/lib/python3.12/site-packages/scipy/io/matlab/_mio.py:226, in loadmat(file_name, mdict, appendmat, **kwargs) 224 variable_names = kwargs.pop('variable_names', None) 225 with _open_file_context(file_name, appendmat) as f: --> 226 MR, _ = mat_reader_factory(f, **kwargs) 227 matfile_dict = MR.get_variables(variable_names) 229 if mdict is not None: File /Applications/anaconda3/lib/python3.12/site-packages/scipy/io/matlab/_mio.py:74, in mat_reader_factory(file_name, appendmat, **kwargs) 54 """ 55 Create reader for matlab .mat format files. 56 (...) 71 72 """ 73 byte_stream, file_opened = _open_file(file_name, appendmat) --> 74 mjv, mnv = _get_matfile_version(byte_stream) 75 if mjv == 0: 76 return MatFile4Reader(byte_stream, **kwargs), file_opened File /Applications/anaconda3/lib/python3.12/site-packages/scipy/io/matlab/_miobase.py:233, in _get_matfile_version(fileobj) 231 if len(mopt_bytes) == 0: 232 raise MatReadError("Mat file appears to be empty") --> 233 mopt_ints = np.ndarray(shape=(4,), dtype=np.uint8, buffer=mopt_bytes) 234 if 0 in mopt_ints: 235 fileobj.seek(0) TypeError: 'NoneType' object is not callable
实际data.py代码
def load_matfiles(file_path): """ Load files with either scipy.io.loadmat or mat73.loadmat. """ try: # Attempt to load the .mat file using scipy data = scipy.io.loadmat(file_path) print(file_path, "loaded with scipy.io.loadmat") return data except Exception as e: print(f"scipy.io.loadmat failed: {e})") print("Trying mat73.loadmat...") try: # Attempt to load the .mat file using mat73 data = mat73.loadmat(file_path) print(file_path, "loaded with mat73.loadmat") return data except Exception as e: print(f"mat73.loadmat also failed: {e}") raise def load_data(mouse_ID): """ Load necessary data files of the selected mouse: - time_binned_SpikeInf - time_binned_DiscreteSpikes - target_positions - darktrial_raw - del_trials """ time_binned_SpikeInf = load_matfiles("../datafiles/"+ mouse_ID +"/time_binned_SpikeInf.mat") time_binned_DiscreteSpikes = load_matfiles("../datafiles/"+ mouse_ID +"/time_binned_DiscreteSpikes.mat") target_positions = load_matfiles("../datafiles/"+ mouse_ID +"/target_positions.mat") darktrial_raw = load_matfiles("../datafiles/"+ mouse_ID +"/darktrial_raw.mat") del_trials = load_matfiles("../datafiles/"+ mouse_ID +"/del_trials.mat") return time_binned_SpikeInf, time_binned_DiscreteSpikes, target_positions, darktrial_raw, del_trials
解决方案
这个错误的核心是numpy的ndarray构造函数被意外覆盖为None,从错误栈最后一行指向np.ndarray(...)的调用就能确认。结合导入自定义模块后才出现问题的现象,按以下步骤排查解决:
排查变量覆盖问题
- 全局搜索
data.py和main.ipynb的所有代码,确认是否存在np.ndarray = None或ndarray = 某个值这类赋值语句——这类代码会直接污染numpy的核心构造函数,导致后续调用失败。 - 重点检查Jupyter单元格中的临时变量,避免未限定作用域的变量名和numpy内置名称冲突。
- 全局搜索
规范模块导入
- 在
data.py开头显式导入所有依赖模块,不要依赖外部Jupyter环境的导入:import scipy.io import mat73 import numpy as np - 避免在模块中使用未显式声明的外部模块引用,防止跨环境的引用冲突。
- 在
重置Jupyter环境
- Jupyter的单元格共享全局命名空间,之前运行的单元格可能残留污染变量。直接重启Jupyter内核,然后按顺序重新运行所有单元格,避免历史变量干扰。
- 若需要快速清空全局变量,可在导入模块前执行
%reset -f(注意会清除所有已定义的变量)。
校验文件路径
- 虽然错误指向
np.ndarray,但也可能是文件路径错误导致文件无法打开,触发后续异常。建议在load_matfiles中使用绝对路径代替相对路径,避免路径解析错误:import os def load_matfiles(file_path): # 转换为绝对路径 abs_path = os.path.abspath(file_path) try: data = scipy.io.loadmat(abs_path) # 后续逻辑不变
- 虽然错误指向
检查numpy版本兼容性
- Python 3.12和部分numpy版本存在兼容性问题,当前环境的numpy版本可能不稳定。尝试升级或降级numpy到适配版本(比如numpy 1.26.x系列),再测试问题是否解决。
内容的提问来源于stack exchange,提问作者Andrew Lau
相关产品推荐
相关产品推荐

