python基础(part12)--模块

鄙人学习笔记
开发工具:Spyder



模块 Module

  • 定义

模块是包含一系列数据、函数、类的文件,通常以.py结尾

  • 作用

让一些相关的数据,函数,类有逻辑的组织在一起,使逻辑结构更加清晰。

导入

Import

  • 语法
import 模块名
import 模块名 as 别名

  • 使用
模块名.成员
  • 作用

将某模块整体导入到当前模块中。

from import

  • 语法
from 模块名 import 成员名[ as 别名]
  • 作用

将模块内的一个或多个成员导入到当前模块的作用域中。

from import *

  • 语法
from 模块名 import *
  • 作用

将某模块的所有成员导入到当前模块。

备注:模块中,以_单下划线开头的,不会被导入,我们称其为隐藏成员。

举个例子1(导入方法1)

创建module01模块,再在同一个文件夹下的另一个模块code02中调用它。

module01.py文件(这个文件在例子1~例子4中都会被调用)

在这里我们先按import的方式,导入模块code02.py

# 导入方式1:
# 导入 模块名称
# 本质:将该模块作用域 赋值给 变量 module01
import module01

#因为module01里的所有内容,都相当于给了变量module01
#则我们想用到module01模块里的成员,就要用module01.变量名 的方法
module01.fun01()
c01 = module01.MyClass01()
c01.fun02()

结果:

举个例子2(导入方法2)

代码:

以上导入方式的本质是将该模块指定成员 赋值给 变量 fun01,MyClass01

结果:

举个例子3(导入方法3)

代码:

以上导入方式中,因为用了*, 所以就是将module01模块中的成员均放入code02模块中(隐藏成员除外)

结果:

备注1:导入方法3容易造成混乱,比如自己也创建了一个方法fun01但是执行时,我们就很难分清,py到底调用的是导入模块内的fun01方法还是,自己创建的fun01方法了。
备注2:若有两个方法重名,py则会利用就近原则,对函数进行调用。

举个例子4(就近原则)

代码1:

结果1:

代码2:

结果2:

举个例子5(单下划线开头的成员)

上面说了,在模块中,以_单下划线开头的成员,不会被导入,那么我们做个实验,看一下,是否真的不能被导入。

若module01.py中添加了一个单下划线开头的变量_fun03,我们再试验一下,是否可以在code02.py中调用。

module01.py文件

①导入方式1

代码:

结果:

②导入方式2

代码:

结果:

③导入方式3

代码:

结果:

报错!
可以看到用前两种导入方式,没有报错,成功导入了;但是用第3种导入方式,却报错了。

模块变量

__all__ 变量:定义可以导出成员,仅对from XX import *语句有效
__doc__变量:获取文档字符串
__file__变量:获取模块对应的文件路径名。
__name__变量:获取模块自身名字,由此可以判断是否为主模块。当此模块作为主模块(第一个运行的模块)运行时,__name__绑定__main__。如果它不是主模块,而是被其他模块导入时,则会存储模块名。

举个例子1(__all__)

我们可以在module01.py中敲入以下代码:

# 可以导出
__all__ = ["fun01","MyClass01", "fun04"]

# 只在第一次被导入时执行
print("我是module01")

def fun01():
    print("fun01")


class MyClass01:
    def fun02(self):
        print("fun02")

def _fun03():
    print("fun03")

def fun04():
    print("fun04")

在code03.py中调用:

from module01 import *

fun01()
fun04()

结果:

若我们将module01.py的__all__中的fun04()方法删除呢?

# 可以导出
__all__ = ["fun01","MyClass01"]

# 只在第一次被导入时执行
print("我是module01")

def fun01():
    print("fun01")


class MyClass01:
    def fun02(self):
        print("fun02")

def _fun03():
    print("fun03")

def fun04():
    print("fun04")

在code03.py中调用:

from module01 import *

fun01()
fun04()

结果:

报错了!

举个例子2(__doc__)

①读本模块的文档字符串

代码:

结果:

②读其他模块的文档字符串

代码:

结果:

举个例子3(__file__)

①读本模块的路径

代码:

结果:

②读其他模块的路径

代码:

结果:

举个例子4(__name__)

①读本模块的名字

代码:

结果:

②读其他模块的名字

代码:

结果:

我们更改一下module01.py,在其中增加__name__

print("我是module01")
print(__name__)

def fun01():
    print("fun01")

class MyClass01:
    def fun02(self):
        print("fun02")
        
def _fun03():
    print("fun03")

运行module01.py模块,得到结果为:


我们再用另一个模块(test03.py)调用module01.py模块:

结果:

加载过程

在模块导入时,模块内的所有语句会被执行。
如果一个模块已经导入,则再次导入时不会重新执行模块内的语句。

分类

①内置模块(builtins),在解析器的内部可以直接使用。
②标准库模块,安装Python时已安装且可直接使用。
③第三方模块(通常为开源),需要自己安装。
④用户自己编写的模块(可以作为其他人的第三方模块)

搜索顺序

导入一个模块,首先搜索是否是内建模块(builtins),如果这个模块不是内建模块, sys.path(这个【模块.属性】记载着我们导包时,所要使用的路径)会提供路径,python则会在这些路径中查找, 查看是否有我们想要加载的模块。

举个例子

我们创建test04.py,并进行测试:

结果:

备注:我们可以看到,sys.path储存的是一个装有路径的列表,意味着它可变,我们也可以通过某种方式,向其中添加路径。

在我们安装第3方模块时,python会将这些第3方模块,放到一些路径中。比如,在某些使用Linux系统的小伙伴的电脑里,如果他使用的是python3.5版本,则我们可以看到python把下载的第3方模块放到了如下路径中:

这样我们就可以直接调用这些第3方模块了。

发布了116 篇原创文章 · 获赞 22 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/m0_37422217/article/details/105137051