python 3模块导入(import)问题一则
2012-12-28 14:24
253 查看
众所周知,python既可以导入包(import package),也可以导入模块(import module),package一般理解为多文件的模块,它是这样定义的,如果一个目录下存在”__init__.py”这个文件,那么python就认为这个目录下的所有文件同属于一个package(这和java的namespace有点像,但是java可不需要这么个特殊文件),如果没有这个文件,那么python认为目录下的py文件都是不相干的独立模块。但是在子目录中你可不能这么干,如果子目录中没有”__init__.py”,那么该目录下的程序算是白写了,根本没有办法引用。当然,也不是绝对的,除非绕个大弯儿:设置当前目录,然后导入,然后重设当前目录。比如,程序需要使用test目录中的模块,而test目录不是package,你只能这样做:
最方便的引入,当然是同一个目录的模块(除了及其简单的程序,很少有人会使用这种扁平的目录结构),那是想怎么导入就怎么导入。比如在主程序中想要使用另一个文件模块中的函数,只需要直接导入即可:
testfuncs.nousefunc() #通过模块的名字引用其中的函数
4: from testfuncs import nousefunc #导入模块中的函数
5: nousefunc() #直接调用导入的函数
上面只是最简单的情况,如果文件中定义的是class怎么样呢,实际使用也是差不多的,不过要多一次构造class的实例的调用:
obj.func1() #通过模块的名字引用其中的class,然后才到类的函数,注意类要实例化
4: from testclass import TestClass #导入模块中的类
5: obj=TestClass(); #实例化类
6: obj.func1() #调用函数
如果都是这种从程序中引入同目录或者子目录的包,那么事情就简单了,但是如果是同为子目录中的模块,要引入兄弟目录中的模块或类,要怎么办呢?例如,如下的目录结构:
图中src目录就是程序的顶层目录,也是包导入的顶层package,pub目录及其子目录是公用程序所在。在这种情况下,最好的方法就是在主程序中(一般位于应用的源程序的根目录,如图中的start.py),把所有下级的目录都缴入的sys.path中,然后在子目录中的模块中,只要使用完全限定的包名引入其他子目录中的模块或者类就可以了。然而现实的情况往往不那么尽如人意,比如为公用包写的测试程序需要放在pub/test目录下,测试目标在pub/data目录下,这是不能寄希望与应用的主程序了,因为此时不会去运行应用程序。这种情况下,启动程序和被引用的包同在一个父目录的子目录中。此时该怎么办呢,还是老办法,要把父目录(src/pub)和(src/pub/data、src/pub/test)目录都要加入sys.path中,然后再用
绝对的方式进行引入(import pub.data.datautil / from pub.data.datautil import DataUtil)。每一个需要的模块都要这么干,因此,我特地写了一个函数,来自动的处理这种情况:
总结,这么做之后解决了对于测试单个功能或模块的导入问题,但是在从应用的顶层目录中运行程序时,还是只能使用Python 3的"from ."来做相对导入,这还真是纠结。
This work is licensed under a Creative Commons Attribution Non-commercial license.
os.chdir("test")
import testfuncs
os.chdir("..")
最方便的引入,当然是同一个目录的模块(除了及其简单的程序,很少有人会使用这种扁平的目录结构),那是想怎么导入就怎么导入。比如在主程序中想要使用另一个文件模块中的函数,只需要直接导入即可:
import testfuncs #直接导入模块(也就是不带扩展名的文件名)
testfuncs.nousefunc() #通过模块的名字引用其中的函数
4: from testfuncs import nousefunc #导入模块中的函数
5: nousefunc() #直接调用导入的函数
上面只是最简单的情况,如果文件中定义的是class怎么样呢,实际使用也是差不多的,不过要多一次构造class的实例的调用:
import testclass #直接导入模块(也就是不带扩展名的文件名)
obj.func1() #通过模块的名字引用其中的class,然后才到类的函数,注意类要实例化
4: from testclass import TestClass #导入模块中的类
5: obj=TestClass(); #实例化类
6: obj.func1() #调用函数
如果都是这种从程序中引入同目录或者子目录的包,那么事情就简单了,但是如果是同为子目录中的模块,要引入兄弟目录中的模块或类,要怎么办呢?例如,如下的目录结构:
图中src目录就是程序的顶层目录,也是包导入的顶层package,pub目录及其子目录是公用程序所在。在这种情况下,最好的方法就是在主程序中(一般位于应用的源程序的根目录,如图中的start.py),把所有下级的目录都缴入的sys.path中,然后在子目录中的模块中,只要使用完全限定的包名引入其他子目录中的模块或者类就可以了。然而现实的情况往往不那么尽如人意,比如为公用包写的测试程序需要放在pub/test目录下,测试目标在pub/data目录下,这是不能寄希望与应用的主程序了,因为此时不会去运行应用程序。这种情况下,启动程序和被引用的包同在一个父目录的子目录中。此时该怎么办呢,还是老办法,要把父目录(src/pub)和(src/pub/data、src/pub/test)目录都要加入sys.path中,然后再用
绝对的方式进行引入(import pub.data.datautil / from pub.data.datautil import DataUtil)。每一个需要的模块都要这么干,因此,我特地写了一个函数,来自动的处理这种情况:
import os,sys import TestClass import testfuncs; from TestClass import TestClass; def _prepareRelativeImport(layer=2): """ 为相对引用做准备,以便下层目录中的模块,相对引用[本目录]以及[父目录]和[兄弟目录]中的模块。 参数layer,表示引入到多少层父目录。默认为2->引入本目录和父目录;3->引入本目录、父目录和祖父目录。 """ import sys,os; curP=os.path.abspath(os.path.dirname(__file__)); oriP=curP;__package__=curP.rpartition(os.path.sep)[2]; print('\r\ncurdir=',curP); while layer>=0: layer-=1; if not curP in sys.path:sys.path.append(curP); pa=curP.rpartition(os.path.sep);curN=pa[2];pp=pa[0];os.chdir(pp); #if '__init__' in ''.join(os.listdir(curP)):__import__(curN); curP=pp; os.chdir(oriP); if __name__=='__main__': if not '__file__' in dir():__file__=os.path.abspath('.')+os.path.sep+"1.py"; _prepareRelativeImport(2) from TestClass import TestClass; from pub.test.TestClass import TestClass; from pub.data.CompareOperator import CompareOperators print('\r\nTest of RelativeImport done!')
总结,这么做之后解决了对于测试单个功能或模块的导入问题,但是在从应用的顶层目录中运行程序时,还是只能使用Python 3的"from ."来做相对导入,这还真是纠结。
This work is licensed under a Creative Commons Attribution Non-commercial license.
相关文章推荐
- Python 被导入模块多次被加载的问题(基于python的import机制)
- Python中import导入上一级目录模块及循环import问题的解决
- 在python用import或者from...import来导入相应的模块
- Python包和模块的导入问题
- import导入模块 【python】
- Python 模块导入路径问题
- Python模块的交叉引用(导入循环)问题分析
- [置顶] 关于python中requests模块导入问题
- python模块以及导入出现ImportError: No module named 'xxx'问题
- python 函数、模块、包及import导入方法
- Python 模块导入路径问题
- Python 在命令行中的import 模块找不到的问题
- python import导入模块执行流程分析
- python 2.7导入模块问题
- python安装第三方模块报错的问题----pip问题(Command "c:\users\win10\python\python.exe -u -c "import setuptools)
- Python 模块导入路径问题
- Python 模块导入路径问题
- python 导入MySQLdb模块 出现的问题 并测试
- python: import模块的相关问题
- windows 下Python import 导入自定义模块