Python——模块

一、模块的介绍

1.1 什么是模块

​ 模块就是一系列功能的集合体,分为三大类

  • 1.1.1 内置的模块

  • 1.1.2 第三方模块

  • 1.1.3 自定义模块

    • 一个python文件本身就是一个模块,文件名m.py,模块名叫m
  • 了解:模块分为四种形式

    '''
    1、使用python编写的.py文件
    2、已被编译为共享库或DLL的c或c++扩展
    3、把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
    4、使用c编写并链接到python解释器的内置模块
    '''
    

1.2 为何要有模块

  • 内置与第三方的模块拿来就用,无需定义,可以极大的提升自己的开发效率
  • 自定义模块:可以将程序的各部分功能提取出来放到一个模块中为大家共享使用,减少代码冗余,程序组织结构更加清晰

二、模块的使用

2.1 import语句

import 模块名
# 1、首次导入模块会发生3件事
    # 1、执行foo.py
    # 2、产生foo.py的名称空间,将foo.py运行过程中产生的名字都丢到foo的名称空间中
    # 3、在当前文件中产生的有一个名字foo,该名字指向2中产生的名称空间
# 之后的导入,都是直接引用首次导入产生的foo.py名称空间,不会重复执行代码(即不会重复导入同一模块)

# 2、引用:
# print(foo.x)
# print(foo.get)
# print(foo.change)
# 强调1:模块名.名字,是指名道姓地问某一个模块要名字对应的值,不会与当前名称空间中的名字发生冲突
# 强调2:无论是查看还是修改操作的都是模块本身,与调用位置无关

# 3、可以以逗号为分隔符在一行导入多个模块(不建议在一行同是导入多个模块)
# 4、导入模块的规范
	#I. python内置模块
    #II. 第三方模块
    #III. 程序员自定义模块
    import time
    import sys
    
    import 第三方1
    
    import 自定义模块1
# 5、import 。。。 as 。。。
import foo as f # f=foo
f.get()

# 6、模块是第一类对象

# 7、自定义模块的命名应该采用纯小写+下划线的风格

# 8、可以在函数内导入模块
def func():
    import foo
  • 执行py文件与导入py文件的区别

    程序执行与模块引用的关系图

    # 执行py文件时,产生对应py文件的名称空间,当该py文件的程序执行结束时名称空间才被回收
    # 导入py文件时,py文件被当作模块引用,第一次导入模块时产生模块的名称空间,即导入的py文件的名称空间
    # 当被导入py文件不再被其他文件所引用,即导入的py文件的引用计数为0时才会被回收
    '''
    1、当foo.py被运行时,__name__的值为"__main__"
    2、当foo.py被当作模块导入时,__name__的值为"foo"
    if __name__ == '__main__':
    	print('文件被执行')
    else:
    	print('文件被导入')
    '''
    
    # import的优缺点
    '''
    import导入模块在使用时必须加前缀"模块."
    优点:肯定不会与当前名称空间的名字冲突
    缺点:加前缀显得麻烦
    '''
    

2.2 from-import语句

from...import...

# from...import...导入也发生了三件事
# 1、产生一个模块的名称空间
# 2、运行foo.py讲运行过程中产生的名字都丢到模块的名称空间
# 3、在当前名称空间拿到一个名字,该名字指向模块名称空间中的某一个内存地址
from foo import x # x=foo中1的内存地址
from foo import get
from foo import change

# x=33333
# print(x)
get()
change()
get()
print(x)
from foo import x # x=新的内存地址(0的内存地址)
print(x)

# from...import...导入模块在使用时不用加前缀
'''
优点:代码更精简
缺点:容易与当前名称空间混淆
from foo import x # x=foo中1的内存地址
x=1111
'''

# 一行导入多个名字(不推荐)
# from foo import x,get,change

# *: 导入模块中的所有名字(大多数情况下不推荐使用,极容易与当前名称空间的名字混淆)
# 当你需要用到同一个模块中的多个名字时,
# 此时可以使用*来进行代码精简,但也需要权衡,避免与当前名称空间的名字混淆

# 了解:__all__ 控制*代表的名字有哪些
from foo import *
print(x)
print(get)
print(change)

# 起别名
from foo import get as g

2.3 循环导入问题

# m1.py
print('正在导入m1')
# from m2 import y
def f1():
    from m2 import y
    print(y)
x='m1'

# m2.py
print('正在导入m2')
# from m1 import x
def f2():
    from m1 import x
    print(x)
y='m2'

# run.py
import m1
m1.f1()

2.4 搜索模块的路径与优先级

# 无论是import还是from...import在导入模块时都涉及到查找问题
# 优先级:
#	1、从内存找(内置模块)
#	2、按照sys.path中存放的文件的顺序依次查找要导入的模块
import sys
# 值为一个列表,存放了一系列的文件夹,
# 其中一个文件夹是当前执行文件所在的文件夹
print(sys.path) 

# 了解:sys.modules查看已经加载到内存中的模块
# 针对模块的优化方案
import sys
import foo
def func():
    import foo
func()
print(sys.modules)

# 找foo.py就把foo.py的文件夹临时添加到环境变量中
# 然后导入foo模块,程序结束append添加的环境变量就会被删除
sys.path.append(r'文件夹路径')

2.5 区分py文件的两种用途

#foo.py
...
if __name__ == '__main__':
    print('文件被执行')
    # oo.py被当做脚本执行时运行的代码
else:
    print('文件被导入')
    # foo.py被当做模块导入时运行的代码

2.6 编写一个规范的模块

  • 该文件既是给自己用的,也有可能会被其他人使用,因而代码的可读性与易维护性显得十分重要,为此我们在编写一个模块时最好按照统一的规范去编写

    "The module is used to..." #模块的文档描述
    
    import sys #导入模块
    
    x=1 #定义全局变量,如果非必须,则最好使用局部变量,这样可以提高代码的易维护性,并且可以节省内存提高性能
    
    class Foo: #定义类,并写好类的注释
        'Class Foo is used to...'
        pass
    
    def test(): #定义函数,并写好函数的注释
        'Function test is used to…'
        pass
    
    if __name__ == '__main__': #主程序
        test() #在被当做脚本执行时,执行此处的代码
    
posted @ 2020-03-26 11:20  群青-Xi  阅读(156)  评论(0编辑  收藏  举报