1. 首页
  2. Python

Python 里 import机制的一些麻烦,你了解多少呢?

“u003Cdivu003Eu003Cpu003Eu003Cstrongu003Esys.path 和 Working directory 是不同的u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Eu003Cstrongu003E1. Working Directory 工作目录u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Eworking directory 是在程序中通过相对路径访问文件的起始点,是操作系统的概念,所有程序都会涉及到,在python中你可以通过下面的代码得到:u003Cu002Fpu003Eu003Cpreu003Eos.getcwd() # get current working directoryu003Cbru003Eu003Cu002Fpreu003Eu003Cpu003E它可能会影响你打开、保存文件, 只要不在程序中修改,在哪里开启的程序,working directory 就在哪里。u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fdfic-imagehandleru002F5a62f0bc-a004-49b3-a0a0-03abea4aafa1″ img_width=”1200″ img_height=”800″ alt=”Python 里 import机制的一些麻烦,你了解多少呢?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003E举个例子:u003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Epython xxx.py 与 python projectu002Fxxx.py 虽然运行的是同一个目录下同一个程序,但是工作目录却是不一样的。u003Cu002Fpu003Eu003Cpu003E这和c语言类似:u003Cu002Fpu003Eu003Cpu003E.u002Fa.out与 .u002Fprojectu002Fa.out 工作目录是不一样的。u003Cu002Fpu003Eu003Cpu003E我们在程序里面通过相对路径访问一个资源,都是依赖于这个运行时才确定的working directory的,而且它是全局共享的,不受代码文件在哪个子目录的影响。u003Cu002Fpu003Eu003Cpu003E初学者可能会误以为module1u002Fa.py 中写的代码与 modeule2u002Fa.py中写的代码 working direcotry 不同,open(‘xx.txt’) 会打开各自目录下的xx.txt。但这是错误的看法,在程序运行后他们会共享一个working directory,它由运行时调用的路径确定。u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp9.pstatp.comu002Flargeu002Fdfic-imagehandleru002Feb23fbc6-f0ca-4a41-8a03-30089dcd85d3″ img_width=”1200″ img_height=”919″ alt=”Python 里 import机制的一些麻烦,你了解多少呢?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003Eu003Cstrongu003E2. 不是环境变量的path:sys.pathu003Cu002Fstrongu003Eu003Cu002Fpu003Eu003Cpu003Esys.path 也是程序运行时所有模块共享的, 它表示是import 查找的路径, 你可能会认为 sys.path与working directory 是一样的,但其实不是,sys.path 是由开始运行的文件(入口文件)位置决定的u003Cu002Fpu003Eu003Cpu003Epython xxx.py 与 python projectu002Fxxx.py 工作目录不同,但是sys.path却相同,都是xxx.py 所在的位置。这样的机制保证了import 不受执行路径的影响是十分合理的设计。但是,有些时候,我们会看到有人喜欢把这个开始运行的入口文件放在子目录中(虽然我们并不建议这样做,但是在程序debug的时候,我们希望单独运行一个文件,这种情况还是时有发生),例如这个入口函数在这里:mainu002Fmain.py 当我们 执行 python mainu002Fmain.py 的时候,sys.path 就会进入到main 目录中,这样main.py 想要 import main 目录外的模块就会出问题,例如import util.xxx 就会出现 ModuleNotFoundError, 就算本目录下的文件 import main.xxx 也会出现错误,因为sys.path 不对。u003Cu002Fpu003Eu003Cpu003E这种情况怎么办呢?我看到过几种做法:u003Cu002Fpu003Eu003Colu003Eu003Cliu003Esys.path.append(‘..’) 将上一级目录 append 进来u003Cu002Fliu003Eu003Cliu003E非常不推荐这种做法,动态改变sys.path会使静态分析工具失效,例如pycharm 等IDE的代码提示。这在大型项目中会极大降低代码的可阅读性、增加开发难度u003Cu002Fliu003Eu003Cliu003E这是软件开发的灾难。u003Cu002Fliu003Eu003Cliu003E使用相对路径import .main.xxx ,from .. import xxxu003Cu002Fliu003Eu003Cliu003E同样非常不推荐这样做,特别是我们只是想临时debug一下子模块中的包的时候,修改好后还需要改回去,十分繁琐,还有可能带来不一致的问题u003Cu002Fliu003Eu003Cliu003E这是软件开发的灾难。u003Cu002Fliu003Eu003Cliu003E[ 推荐做法 ] 使用python -m main.main 执行程序u003Cu002Fliu003Eu003Cliu003E此时sys.path就在执行这行代码时所在的目录,也就是working directory, 而不会进入main所在的位置,这是十分简单的解决方法,不会带来新的问题,但是我们却看到许多工作大量使用`sys.path.append(‘..’), importlib.import_module 之类的动态代码解决这类问题,这种动态性的修改会给软件的维护带来很多不必要的麻烦u003Cu002Fliu003Eu003Cu002Folu003Eu003Cpu003E这是软件开发的灾难。u003Cu002Fpu003Eu003Cpu003EPython和 Java的import机制不同点对比u003Cu002Fpu003Eu003Cpu003Epython没有java不引用直接通过绝对路径调用的方式u003Cu002Fpu003Eu003Colu003Eu003Cliu003Ejava 不能重命名,python 可以 import u003Cemu003Eoriginal_nameu003Cu002Femu003E as u003Cemu003Enew_nameu003Cu002Femu003Eu003Cu002Fliu003Eu003Cliu003Ejava不能import package,而python可以import package,python package的内容在 __init__.py 中定义u003Cu002Fliu003Eu003Cliu003E可以认为python import 一个文件夹(package)就是在import 那个文件夹下的__init__.py ,这个文件在python2 中必须显示提供,在python3中会默认有个空的。 需要注意的是如果__init__.py中什么都没有,那么import这个包是没用的,所以我们通常会在__init__.py中import这个包内的一些函数u002F类,这样可以减少import的深度,用好它是提高代码可读性的有力封装工具python import后仍然要使用全名 u003Cu002Fliu003Eu003Cliu003Eimport torch.nn.Convu003Cu002Fliu003Eu003Cliu003Ejava:Conv.xxxxu003Cu002Fliu003Eu003Cliu003Epython : torch.nn.Conv.xxxxu003Cu002Fliu003Eu003Cu002Folu003Eu003Cpu003E这种情况推荐重命名u003Cu002Fpu003Eu003Cdiv class=”pgc-img”u003Eu003Cimg src=”http:u002Fu002Fp1.pstatp.comu002Flargeu002Fdfic-imagehandleru002Fcca936df-54a0-431b-9503-85dabadf8ab1″ img_width=”1023″ img_height=”682″ alt=”Python 里 import机制的一些麻烦,你了解多少呢?” inline=”0″u003Eu003Cp class=”pgc-img-caption”u003Eu003Cu002Fpu003Eu003Cu002Fdivu003Eu003Cpu003E最后多说一句,小编是一名python开发工程师,这里有我自己整理了一套最新的python系统学习教程,包括从基础的python脚本到web开发、爬虫、数据分析、数据可视化、机器学习等。想要这些资料的可以关注小编,并在后台私信小编:“01”即可领取。u003Cu002Fpu003Eu003Chru003Eu003Cu002Fdivu003E”

原文始发于:Python 里 import机制的一些麻烦,你了解多少呢?

主题测试文章,只做测试使用。发布者:逗乐男神i,转转请注明出处:http://www.cxybcw.com/12892.html

联系我们

13687733322

在线咨询:点击这里给我发消息

邮件:1877088071@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code