Python代码以.py文件形式保存。而每个.py文件都可以看作是一个模块。当一个模块调用另一个模块时,便需要import语句。
在此前的章节中,我们已看到import语句的使用。
若在同一package下,则只需要调用import moduleName即可。否则需要使用from packageName import moduleName。
网上各种教程有描述,“若在同一package下,则只需要调用import moduleName即可”,但有时IDE仍会提示“Unresolved Import”。矛盾的是,虽然有错误提示,脚本却能正确执行。这是为什么呢?
执行结果如下
it's module1
sys path = ['/Users/breakloop/eclipse-workspace/helloworld/src/demo/module', '/Users/breakloop/eclipse-workspace/helloworld/src', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip']
hello
首先,脱离IDE,在命令行模式下,进入python指令,import相同目录下的模块,确实不会报错。python会到当前目录下,以及sys.path (sys.path是一个路径列表)中查找引入的模块。这也是代码能够正确执行的原因。
而IDE之所以报错,是因为IDE仅仅将scr目录加入了PYTHONPATH,其子目录并不再PYTHONPATH中,
因此,IDE认为未能找到模块,因此提示错误。
当然,解决的办法也很简单。有3种
(1)使用from package import module的方式
import sys
from demo.module import module1
if __name__ == '__main__':
print("sys path =", sys.path)
module1.hello()
(2)使用import package.module的方式
import sys
import demo.module.module1 as m1
if __name__ == '__main__':
print("sys path =", sys.path)
m1.hello()
(3)在PYTHONPATH中添加当前目录。
通过以上几个方法,我们也了解了,如何告诉PYTHON从何处寻找module.
from demo.module import module1
if __name__ == '__main__':
print(dir(module1))
print()
相应输出为
it's module1
['__builtins__', '__bye__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'hello']
dir()方法可以输出模块的所有属性和方法(包括私有方法)
from demo.module import module1
if __name__ == '__main__':
help(module1)
print()
相应输出为
Help on module demo.module.module1 in demo.module:
NAME
demo.module.module1 - Created on 2018年6月24日
DESCRIPTION
@author: breakloop
FUNCTIONS
__bye__()
hello()
FILE
/Users/breakloop/eclipse-workspace/helloworld/src/demo/module/module1.py
help方法给出了module1的各种信息,包括:注释头,方法列表(包括私有方法),模块位置等。
我们在使用IDE创建模块时,通常会有一段代码
if __name__ == '__main__':
pass
当执行模块本身时,__name__将被置为“__main__”,因此我们可以根据__name__的值,来判断当前模块是被调用,或是自身在执行。例如,module1
if __name__ == '__main__':
print("inside")
else:
print("it's module1")
def hello():
print("hello")
def __bye__():
print("bye")
当运行module1时,输出“inside”。当被外部引用时,输出“it's module1”