结论:在需要
import pandas
时,同级目录下不要有unittest.py
同名文件,否则,会与pandas
自带的unittest
冲突,导致import pandas
失败。
错误使用场景复现
建立了一个 testpandas.py,同时,在同级目录下建立了一个 unittest.py。
在 testpandas.py 中 import pandas, 运行发现报错。
报错信息
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\pandas\__init__.py", line 13, in <module>
__import__(dependency)
File "C:\Python27\lib\site-packages\numpy\__init__.py", line 187, in <module>
from .testing import Tester
File "C:\Python27\lib\site-packages\numpy\testing\__init__.py", line 10, in <module>
from unittest import TestCase
ImportError: cannot import name TestCase
Traceback (most recent call last):
File "C:/Users/Bug/PycharmProjects/md-jobs-latest/app/mdjob/testpandas.py", line 8, in <module>
import pandas
File "C:\Python27\lib\site-packages\pandas\__init__.py", line 20, in <module>
"Missing required dependencies {0}".format(missing_dependencies))
ImportError: Missing required dependencies ['numpy']
原因分析
根据报错,查看C:\Python27\lib\site-packages\numpy\testing\__init__.py
源码,如下:
"""Common test support for all numpy test scripts.
This single module should provide all the common functionality for numpy tests
in a single location, so that test scripts can just import it and work right
away.
"""
from __future__ import division, absolute_import, print_function
from unittest import TestCase
from ._private.utils import *
from ._private import decorators as dec
from ._private.nosetester import (
run_module_suite, NoseTester as Tester
)
__all__ = _private.utils.__all__ + ['TestCase', 'run_module_suite']
from numpy._pytesttester import PytestTester
test = PytestTester(__name__)
del PytestTester
可以看到,第 10 行的from unittest import TestCase
与上图testpandas.py
同级目录下的unittest
(自己创建的)产生同名冲突。
也就是说,在unittest
中找不到TestCase
。也可以理解为,自己创建的unittest
从名称上污染了官方的unittest
,错误的引用了自己建的unittest
,所以报错。
解决方式
在需要 import pandas
时,同级目录下不要有 unittest.py
的同名文件,否则,会与pandas
自带的unittest
冲突,导致 import pandas
失败。
拓展阅读:from future import absolute_import 的作用
关于from __future__ import absolute_import
的作用:
直观地看就是说”加入绝对引入这个新特性”。说到绝对引入,当然就会想到相对引入。
那么什么是相对引入呢?比如说,你的包结构是这样的:
pkg/
pkg/init.py
pkg/main.py
pkg/string.py
如果你在main.py
中写import string
,那么在Python 2.4或之前, Python会先查找当前目录下有没有string.py, 若找到了,则引入该模块,然后你在main.py中可以直接用string了。如果你是真的想用同目录下的string.py
那就好,但是如果你是想用系统自带的标准string.py
呢?那其实没有什么好的简洁的方式可以忽略掉同目录的string.py而引入系统自带的标准string.py。这时候你就需要from __future__ import absolute_import
了。这样,你就可以用import string
来引入系统的标准string.py
, 而用from pkg import string
来引入当前目录下的string.py
了