当前位置: 首页 > news >正文

门户网站构建国家备案网

门户网站构建,国家备案网,做网站图片太多怎么办,sem竞价教程前言 Python中的包管理,一直是我比较困惑的一点。 python导入另一个文件,会不会执行另一个文件的?python是怎么找到具体的包的?包名不会重复吗?目录层级结构比较复杂的时候,怎么导入包? 简单实例…

前言

Python中的包管理,一直是我比较困惑的一点。

  1. python导入另一个文件,会不会执行另一个文件的?
  2. python是怎么找到具体的包的?包名不会重复吗?
  3. 目录层级结构比较复杂的时候,怎么导入包?

简单实例

同级目录下,main.py可以按照如下方式导入mymath.py中的变量和函数
目录结构如下

- python_package
--main.py
--mymath.py
# mymath.py
PI = 3.14def add(a,b):return a+b
# main.py
import mymathprint(mymath.add(1, 2))

import本质是什么?

那么我们需要深入研究一下,import到底做了什么呢?
首先我们要看看mymath到底是个什么?

print(type(mymath))
# <class 'module'>

可以看到mymath其实是一个变量,指向了module类的实例。所以import就是生成了一个module实例,然后赋值给了变量mymath
于是我们就像变量一样使用它,如下

mm = mymath
print(mymath.add(1, 2))
print(mm.add(1, 2))

相当于给mymath起了一个别名,因为这种起别名的方式还挺常见的,所以Python有特殊的语法专门做这个事

# python在创建module后,就将其赋值给mm变量,然后就没有mymath变量了
import mymath as mm
print(mm.add(1, 2))

ok,我们知道了mymath是指向一个module实例的变量
那么import是怎么生成这个module实例的呢?
我们在遇到import实例的时候,python首先会查询,mymath有没有被import过。
如果没有:python就会将mymath.py读取到内存中,并运行。
而如果已经被import过了就找到当时创建的module,并把它直接赋值给import后面的变量。
所以如果import了两次同样的文件,那这个文件只会在被第一次import时,运行一次。
我们来验证一下

# 在mymath.py中加入打印
print("exeute mymath.py")
PI = 3.14def add(a,b):return a+b
# main.py多次引入
import mymath as mm
import mymath as mm2
# 分别打印id
print(id(mm))
print(id(mm2))
exeute mymath.py
2509003175824
2509003175824

可以看到mymath.py只被运行了一次,且mm和mm2的ID是相同的。说明他们指向同一个module对象
mymath.py运行时,import创建的module就会成为mymath.py的全局命名空间。所以说mymath.py中定义的全局变量,就会被定义在import创建的module

我们可以通过dir()函数来看到mm定义的内容

# main.py
import mymath as mm
import mymath as mm2print(dir(mm))
['PI', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'add']

可以看到PIadd都在这个全局变量中

现在我们来个骚操作

# mymath.py
print("exeute mymath.py")
PI = 3.14def add(a,b):return a+bdef add_global(name,value):g = globals()g[name] = value
# main.py
import mymath as mm
import mymath as mm2mm.add_global("E",2.71)
print(mm.E)

mymath中本来是没有E这个变量的,但是通过调用方法给他添加了这个变量后,就有了。
这说明mm就是mymath.py运行的全局命令空间。
python import还有另外一种写法。

# main.py
from mymath import PI

这样做还是会为mymath创建module并且运行mymath.py
但这次不会把module赋值给mymath变量了,而是把PI的值直接赋值给当前命名空间的PI变量
注意这里是一个赋值的操作,赋值之后mymath.py中的PI就和当前文件中的PI没有任何的关系了
也就是说,如果我们修改当前的PI值是不会修改mymath.py中的PI值的

from mymath import PI
import mymath as mmPI = 9999
print(f"PI in main: {PI}")
print(f"PI in mymath: {mm.PI}")
exeute mymath.py
PI in main: 9999
PI in mymath: 3.14

所以说import的本质就是创建命名空间,也就是module,然后对变量进行赋值的一个过程

代码从哪找?

好,现在我们创建了module就应该找相应的Python文件来运行了。
那么从哪里找呢?
就是从sys.path中查找

from mymath import PI
import mymath as mm
import sysprint(sys.path)
['d:\\pythonProject\\python_package', 'D:\\Develop\\python\\python310\\python310.zip', 'D:\\Develop\\python\\python310\\DLLs', 'D:\\Develop\\python\\python310\\lib', 'D:\\Develop\\python\\python310', 'D:\\Develop\\python\\python310\\lib\\site-packages']
# 可以看到sys.path的第一项,就是main脚本所在的目录
# 还包含了python自带的库的目录
# 以及安装的第三方的库的目录 D:\\Develop\\python\\python310\\lib\\site-packages

sys.path就是一个普通的list,所以我们是可以用代码对它进行更改的。
当然除了通过代码,我们还可以在运行Python的时候,指定环境变量PYTHONPATH来改变sys.path的值
如下

PYTHONPATH=D:\a\b\c python main.py$env:PYTHONPATH="D:\\a\\b\\c"; python main.pyPS D:\pythonProject\python_package> $env:PYTHONPATH="D:\\a\\b\\c"; python main.py
exeute mymath.py
['D:\\pythonProject\\python_package', 'D:\\a\\b\\c', 'D:\\Develop\\python\\python310\\python310.zip', 'D:\\Develop\\python\\python310\\DLLs', 'D:\\Develop\\python\\python310\\lib', 'D:\\Develop\\python\\python310', 'D:\\Develop\\python\\python310\\lib\\site-packages', 'D:\\Develop\\python\\python310\\lib\\site-packages\\win32']

可以看到D:\\a\\b\\c已经被加到sys.path变量中了。
于是在import时python就可以从这些路径去寻找mymath.py文件了
如果找到了皆大欢喜,如果找不到python就会去寻找mymath的目录
mymath目录中往往还有一个__init__.py,这时python就会去运行__init__.py
带有__init__.py目录的优先级是比文件要高的,
在这里插入图片描述

execute __init__.py
['D:\\pythonProject\\python_package', 'D:\\Develop\\python\\python310\\python310.zip', 'D:\\Develop\\python\\python310\\DLLs', 'D:\\Develop\\python\\python310\\lib', 'D:\\Develop\\python\\python310', 'D:\\Develop\\python\\python310\\lib\\site-packages', 'D:\\Develop\\python\\python310\\lib\\site-packages\\win32']

可以看到,我们的程序只打印出了__init__.py的输出。这说明我们的程序确实加载了__init__.py文件,没有加载mymath.py文件
而这个目录其实就是所谓的package,
注意:无论有没有__init__.py文件,Python都会加载这个目录,只不过如有没有__init__.py这个文件,Python就不运行任何代码了。但是module还是会照常被创建。
我们试试直接创建一个目录mydir

# main.py
import mydirprint(mydir)
<module 'mydir' (<_frozen_importlib_external._NamespaceLoader object at 0x00000170F723DA80>)>

可以看到mydir还是可以被正常的加载

Python也是支持子目录的

我们在mydir下创建subdir。然后我们就可以用如下方式导入子目录

# main.py
import mydir.subdirprint(mydir)
print(mydir.subdir)
<module 'mydir' (<_frozen_importlib_external._NamespaceLoader object at 0x000001D607B1DA50>)>

这时Python会做两件事情

  1. 首先在当前的命名空间中导入mydir
  2. 然后再在mydir的命名空间中导入subdir

我们可以使用dir打印一下两个命名空间,看看里面分别都有什么

# main.py
import mydir.subdirprint(dir())
print(dir(mydir))['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'mydir']
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'subdir']

可以看到在第一个命名空间中有mydir,在第二个命令空间中有subdir

当然我们也可以用一下方式导入子目录
这样就可以将subdir直接导入到当前命名空间中,但这样依然会在mydir的命名空间中也导入subdir

from mydir import subdir
import mydirprint(dir())
print(dir(mydir))
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'mydir', 'subdir']
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'subdir']

可以看到当前命令空间和mydir命名空间中都有了subdir

relative import 相对导入

我们需要在mydir目录中的a.py引入subdir

import mydir.subdir
from . import subdir

总结

  1. import mymath导入包,会在os.path列表下以此去找对应的目录或者文件。目录下带有__init__.py的优先级大于文件
  2. 带有__init__.py的目录,则被称为package
  3. os.path是一个地址路径列表,依次查找对应的目录或者文件以找到的第一个包为准。
  4. import mymath如果是目录则会执行mymath目录下的__init__.py文件,如果是文件mymath.py则执行该文件,然后创建module类的实例赋值给mymath变量
  5. dir()可以查看命名空间中有哪些变量。
http://www.dtcms.com/a/562591.html

相关文章:

  • sourceforge下载提速的方法
  • 网站开发需求分析word微信官网下载安装微信
  • 电影资源分享网站怎么做的网站设计注意因素
  • 郑州建站推广公司优质的广州做网站
  • wordpress 建立网站学生个人网站建设方案书框架栏目
  • 打工人日报#20251102
  • 32HAL——舵机DRV8833驱动电机
  • 上海国际建设总承包公司网站如何在虚拟空间上做多个网站
  • 东莞工程网站建设南通网站建设公司哪个好
  • 企业网站服务费怎么做记账凭证纯文本网站建设
  • 个人做网站还是公众号赚钱好网络工程就业方向
  • 官方网站制作邓州微网站建设
  • 申请域名后可以做自己的网站吗wordpress 手机电脑
  • seo网站排名优化快速排网站群建设需求
  • 免费申请自己的网站郴州市建设局网站
  • .耐思尼克官方网站北京市网页设计
  • 长沙网站建设市场低价网站开发.net
  • 孤能子视角:EIS六线分析之“苏格拉底对话孔子及AI“
  • 【计算机软件资格考试】软考综合知识题高频考题及答案解析2
  • 免费做淘宝客网站攸县网站开发
  • 清润邯郸网站wordpress文章禁止搜索
  • 哈尔滨怎样快速建站oa手机端app下载
  • 网站备案用户名忘了怎么办网站优化可以做哪些优化
  • 品牌推广公司网站关键词优化软件效果
  • 蓬莱市住房和规划建设管理局网站网站代码seo优化
  • 中信建设有限责任公司官方网站成都成华网站建设
  • 郑州网站建设公司咨询做ppt的软件怎么下载网站
  • 有哪些做兼职的设计网站有哪些工作内容怎样做信息收费网站
  • 昆山网站建设哪里好哪个免费的网页制作软件最好
  • 网站外链优化方法成都网站建设案例单招网