代码改变世界

python模块 运行机制 编写方法

2022-04-05 16:58  jym蒟蒻  阅读(148)  评论(0编辑  收藏  举报

文章目录

    • python模块的导入机制:
    • python模块编写方法:

 

#mod1:
def printer(x):
    print(x)
#mod2:
print('hello')
n=1
#mod3:
x=1
y=[2,3]
>>> import mod1
>>> mod1.printer('hello')
hello
>>> from mod1 import printer
>>> printer('hello')
hello
>>> from mod1 import*
>>> printer('hello')
hello
>>> import mod2
hello
>>> mod2.n
1
>>> mod2.n=2
>>> import mod2
>>> mod2.n
2
>>> from mod3 import x,y
>>> x=42
>>> y[0]=42
>>> import mod3
>>> mod3.x
1
>>> mod3.y
[42, 3]
>>> from mod3 import x,y
>>> x=11
>>> import mod3
>>> mod3.x
1
>>> mod3.x=11
>>> mod3.x
11
>>> from mod3 import x,y
>>> x
11

python模块的导入机制:

1.每一个文件都是一个模块,模块是最高级别的程序组织单元,它将程序代码和数据封装起来以便重用。在一个模块文件的顶层定义的所有变量名都成了被导入的模块对象的属性 。

2.一个程序包含多个文件(模块),程序作为一个顶层文件来构造,这个顶层文件使用在模块文件中定义的工具,这些模块也可能使用其他模块定义的工具。我们导入一个模块,就可以获取他的属性并使用它的工具(可被调用的函数或者是简单的数据数值)。可以在不同程序中再次使用某一模块。

3.python自带了很多模块,称为标准链接库。

4.import工作方式:

导入并不是把一个文件文本插入另一个文件,导入是运行时的运算,程序第一次导入指定文件时会执行:1.找模块文件,2.编译成位码,3.执行模块的代码来创建其所定义的对象。模块第一次被导入时才会进行,之后如果导入相同模块,会跳过这几个步骤,只提取内存中已加载的模块对象。

python已经导入的模块保存在一个内置的sys.moudles字典中,在一次导入操作的开始检查该表,如果模块不存在,将会启动那三个步骤。

5.python字节码编译:

程序执行时,python内部会将源代码(文件里的语句)编译成字节码(平台无关)的形式。python将把程序中的字节码保存为一个以.pyc为扩展名的文件。这是一种启动速度的优化,如果没有修改过源代码的话,下一次运行程序,python将会加载.pyc文件并跳过编译步骤。如果源文件的保存时间在字节码保存时间之后,那么再次运行程序时,字节码会重新被创建。

字节码不是机器的二进制代码,它是基于python的一种表现形式。

6.python虚拟机(PVM)

程序编译成字节码之后,字节码将会发送到python虚拟机上来执行。PVM是迭代运行字节码指令的一个大循环,它是python运行的引擎,是python系统的一部分。

PVM循环仍然需要解释字节码,和其他解释器不同,python有它内部的编译步骤。字节码指令相比cup指令需要更多工作。

7.三个步骤具体的细节:

搜索:python查找import语句所引用的模块文件

python模块搜索的路径:程序的主目录,pathonpath目录,标准库目录,.pth文件的内容。这四个组合起来就成了sys.path目录名称字符串列表。python会从左到右搜索这个列表中的目录。

主目录:当你运行一个程序,这个包含程序顶层脚本文件的目录就是主目录,这个目录下的其他模块(文件)将覆盖其他目录下的具有同样名称的模块。这个主目录总是优先被搜索,因此需要小心隐藏标准库模块。如果程序都位于单一的目录,那么所有导入都将会自动工作,不需要配置路径。

pathonpath目录:pythonpath环境变量设置中罗列出的所有目录。

编译:找到符合import语句的源代码文件后,编译成字节码。有时候,如果python在搜素路径上只发现了字节码文件,那么就直接会加载字节码(从而避免了泄露源代码)。

程序顶层文件的字节码是在内部使用之后就被丢弃,而被导入文件的字节码则保存在文件中,从而提高之后导入的速度。因此我们可以看见被导入文件的.pyc字节码文件,但往往看不到程序顶层文件的.pyc字节码文件。

8.模块让程序将其逻辑分割成一些独立完备的软件组件。每个模块的程序代码相互隔离,因此模块最小化了程序内不同部分之间的变量名冲突。

python模块编写方法:

1.使用模块:客户端可以通过import和form语句使用模块文件。

import语句:import会读取整个模块,需要通过模块名称得到模块属性。

form语句:获取模块特定的变量名,from可以把变量名复制到当前作用域,我们可以直接在脚本中使用复制后的变量名,而不需要通过模块。

from*语句:会取得模块顶层所有赋了值的变量名的拷贝。把一个模块的命名空间融入另一个模块中。

2.导入只会发生一次:在交互模式或者程序运行期间,之后的导入没有什么效果。如果第一次导入的时候,对模块中的变量进行初始化,第二次导入后,并不会重新执行此模块的代码,只是从python内部模块表中取出已创建的模块对象。(一般是import两次,但是第二次其实是没用的)

3.import和from属于赋值语句:

import语句:将整个模块对象赋值给一个变量名

from语句:将一个或多个变量名赋值给另一个模块中同名的对象。

from复制的变量名会变成共享对象的引用,修改已取出的不可变对象,不会影响模块中的那个不可变对象的值,但是修改可变对象,会影响模块内的那个可变对象。

以from复制而来的变量名和其源文件没联系(不可变对象),如果想要修改另一个文件的全局变量名,必须使用import

from只加载模块文件的一部分是不可能的,from也是会把整个模块导入到内存中,不管需要复制出多少变量名。

只能用import的场合:使用两个不同模块内定义的相同变量名的变量。