Life, half is memory, half is to continue.
通俗地理解Python的模块
By Vincent. @2021.8.12
通俗地理解Python的模块

1) 模块

① Python模块(Module),是一个Python文件,以.py结尾,包含了Python语句和Python对象定义,模块让你能够有逻辑地组织你的Python代码段。

② 相当于很多类、很多函数包含在一个.py文件,这个.py文件就是一个模块。

③ 模块能定义函数,类和变量,模块里也能包含可执行的代码,即导入模块会自动执行这些代码。

④ 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。

⑤ 推荐所有的模块在Python模块的开头部分导入,而且最好按照下面的顺序:

1. Python标准库模块
2. Python第三方模块
3. 应用程序自定义模块

⑥ 在Python中用关键字import来引入某个模块,比如要导入模块time,就可以在文件最开始的地方用import time来引入。

# functools就是模块,是一个functools.py文件,该文件在搜索在搜索路径下的,reduce是这个文件中的一个方法。
from functools import reduce 

2) import

① import A

1. 在调用模块中的函数时,必须加上模块名调用,因为可能存在多个模块中含有相同名称的函数,此时,如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。为了避免这样的情况,调用函数时,必须加模块名。
2. import time 等价于 from time import *,即把time模块中的所有方法都导入。

import time 

# 第一个time是模块,第二个time是方法,要用模块加方法的形式,因为不同模块可能有相同的方法
print(time.time()) 

运行结果:

import time

# print(sleep(2))     # 会报错,它不知道sleep()方法是哪个模块中的,所以不会去调用
print(time.sleep(2))  # 不报错,仅导入模块时,一定要用 模块.方法 的形式

运行结果:

② from A import b

1. 不会把整个模块导入进来,只会把A模块的b方法导入进来(相当于把这个方法写在文件的开头),不能写模块名。
2. 从A模块里导入一个函数或者一个变量 b。
3. from导入模块,import导入类名,实例化时可直接用类名了。

from time import time  # 仅仅导入了time模块中time方法

print(time())           # 不会报错,不用加模块名
# print(time.time())    # 报错,相当于仅仅把time方法写在本文件头部,不能加模块名
# print(sleep(1))       # 报错,除非用 from time import time,sleep
# print(time.sleep(1))  # 报错,除非用 import time

运行结果:

③ import A as b

1. 将A重新命名为b。

# time重命名为t
import time as t
print(t.time())       # 等价于原来的 print(time.time()),但重命名后不可以用 print(time.time())
#print(time.time())    # 报错,无法再用time作为模块名

运行结果:

④ from A.B.c import d

1. 软件项目来说不可能把所有代码放在一个文件中实现,它们一般会按照一定规则在不同的目录和文件中实现,然后互相调用。
2. 从当前路径下,A文件夹下B文件夹下的c模块中,导入d方法

'''
import p 调用本文件的当前目录下的 p模块
import C.c1 调用当前路径下的C文件夹下的c1.py模块
import C.c2 import c5 调用当前路径下的C文件夹下的c2.py模块中的c5方法 
'''

3) 模块内置属性

① __doc__ 为打印文档说明(只能在文件的最开始,import前面,在后面的字符串不会打印),即文档中的字符串。

② __file__为打印本文件的路径。

③ __all__打印过滤变量、函数和类。

'''
import b1

print(__doc__)
print(__file__)    # 打印本模块的路径
print(__all__)
print(b1.__doc__)
print(b1.__file__) # b1模块的路径
print(b1.__all__)
'''

4) __all__

① 因为模块中可能包含大量的不需要的变量、函数和类,可以通过设置 __all__起到过滤变量、函数和类的作用,变量 __all__ 包含一个列表。

② 在以import * 方式导入时,会导入任意不以下划线打头的全局名词,有 * 的时候才跟 __all__ 搭配使用, 通过__all__起到过滤。

③ 直接用import b1时,即导入b1模块的时候,在b1模块即使有__all__是没有影响的,可以使用b1模块中的任何变量、函数和类。

④ 模块中不使用__all__属性,则导入模块内的所有共有属性,方法和类。

'''
# 以下是b1文件里代码
__all__  =  ['b3','S','b4',b5] # 当用from b1 import * 只能用b3、b4和类S,可以需要过滤的b5,但是未赋值

b3    =     1
b4    =     2
   
clas S:
    pass
    
def s():
    pass
'''

'''
# 当前文件下代码
from b1 import *   # 导入b1模块,用 * 使得调用 __all__
b4 = 5 
print(b3)          # 可以打印b3,为1
print(b4)          # 这里打印b4,为5
k = S()            # 可以类的实例化
s()                # 无法调用函数s()
'''

5) if __name__ == ‘__main__’:

① 当调入别的模块时,通常在模块中写 if __name__ == ‘__main__’: 这样能避免调用其他模块时,这些模块中的函数运行了,但是 if __name__ == ‘__main__’ 以外的函数、变量、类都会运行,相当于把这些抄到了文件的头部,直接运行。

# 以下是b1.py模块内容

print("宝贝入怀")

if __name__ ==  '__main__':
    print("你好")        
'''
import b1  # 导入b1模块,会自动运行 if __name__ ==  '__main__'以外内容,就会打印print("宝贝入怀")

print(__name__)               # 代码在当前文件中跑,该模块的文件名__name__不是文件名,而是__main__。

if __name__ ==  '__main__':
    print(b1.__name__)        # 导入另一个模块的代码,另一个模块的文件名__name__是文件名b1。
'''
扫码分享收藏
扫码分享收藏