目录
1, 什么是模块
py文件就是模块
2, 模块导入流程
导入模块时,先在文件系统的"预定义区域"进行查找,找到则导入成功,否则导入失败
"预定义区域"的值设置在PATHPYTHON环境变量中
解释器中输入命令:sys.path可以查询"预定义区域"的详情,返回的是列表
In [4]: sys.path
Out[4]:
['C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python311\\Scripts\\ipython.exe',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python311\\python311.zip',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python311\\DLLs',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python311\\Lib',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python311',
'',
'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python311\\Lib\\site-packages']
3, 名称空间
3-1, 什么是名称空间
名称空间是变量名到对象的映射
3-2, 名字空间个数
程序运行期间有2~3个名称空间:分别为局部名称空间、全局名称空间、内建名称空间,局部名称空间是函数运行期间存在,全局、内建是程序运行期间一直存在;
3-3, 名称空间的加载顺序
先加载内建名称空间, 再加载全局名称空间, 最后是局部名称空间
3-4, 名称的查找顺序
先在局部名称空间查找,再到全局名称空间查找,最后到内建名称空间查找, 先找到就不在继续查找
4, 导入模块
4-1, import语句导入
通过import 模块名, 导入模块
In [7]: import sys
推荐模块的导入顺序:
先导入python 标准库, 再导入第三方模块, 最后导入自定义模块;使用一个空行分割三类模块导入
在模块顶层导入的,它的作用域为全局, 在函数中导入的,它的作用域为局部
模块只在第一次导入时,才执行,且只执行顶层代码;例入你的模块导入了sys模块, 而你导入的其他5个模块也导入了sys模块,实际上sys模块只被加载了一次
4-2, from-import语句导入
通过from module import name1, 指定模块中的属性导入
In [2]: from random import randint
4-3, 多行导入
当导入的模块里面的属性过多时,可以分多行进行导入
from tkinter import Tk, Frame, Button, Entry, Canvas, Text
from tkinter import LEFT, DISABLED, NORMAL, RIDGE, END
# 推荐使用括号来括起导入的属性
from tkinter import (Tk, Frame, Button, Entry, Canvas, Text, LEFT,
DISABLED, NORMAL, RIDGE, END)
4-4, 导入模块后使用别名
通过import 模块 as 模块别名方式, 给导入的模块去别名
# 导入tkinter模块并取别名tk
In [6]: import tkinter as tk
5, 模块的内建函数
5-1, __import__()
该函数的功能是为了让有特殊要求的用户覆盖它本身
__import__(module_name [, globals[, locals[, fromlist]]])
module_name是要导入模块的名字字符串表示
globals是包含当前全局符号表的名字字典, 默认为globals()
locals是包含局部符号表的名字字典,默认为locals()
fromlist是一个使用from-import语句所导入符号的列表,默认[]
# 等价于import sys
In [1]: sys = __import__('sys')
5-2, globals()
该函数返回当前的全局名称空间字典
5-3, locals()
该函数返回当前的局部名称空间字典, 在函数内部调用,则返回当前函数的局部空间字典;在函数外部调用,则返回与globals一致
In [2]: def foo():
...: print('calling foo...')
...: a_string = 'bar'
...: a_int = 42
...: print("foo's globals:", globals())
...: print("foo's locals:", locals())
...:
In [3]: print("__main__'s globals:", globals())
__main__'s globals: {'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'sys', 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'print("__main__\'s globals:", globals())'], '_oh': {}, '_dh': [WindowsPath('C:/Users/Administrator')], 'In': ['', 'sys', 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'print("__main__\'s globals:", globals())'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x000002C52E64CD90>>, 'exit': <IPython.core.autocall.ExitAutocall object at 0x000002C52E648910>, 'quit': <IPython.core.autocall.ExitAutocall object at 0x000002C52E648910>, 'open': <function open at 0x000002C52D4DC220>, '_': '', '__': '', '___': '', '_i': 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', '_ii': 'sys', '_iii': '', '_i1': 'sys', '_i2': 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'foo': <function foo at 0x000002C52E9BBE20>, '_i3': 'print("__main__\'s globals:", globals())'}
In [4]: print("__main__'s locals:", locals())
__main__'s locals: {'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'sys', 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'print("__main__\'s globals:", globals())', 'print("__main__\'s locals:", locals())'], '_oh': {}, '_dh': [WindowsPath('C:/Users/Administrator')], 'In': ['', 'sys', 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'print("__main__\'s globals:", globals())', 'print("__main__\'s locals:", locals())'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x000002C52E64CD90>>, 'exit': <IPython.core.autocall.ExitAutocall object at 0x000002C52E648910>, 'quit': <IPython.core.autocall.ExitAutocall object at 0x000002C52E648910>, 'open': <function open at 0x000002C52D4DC220>, '_': '', '__': '', '___': '', '_i': 'print("__main__\'s globals:", globals())', '_ii': 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', '_iii': 'sys', '_i1': 'sys', '_i2': 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'foo': <function foo at 0x000002C52E9BBE20>, '_i3': 'print("__main__\'s globals:", globals())', '_i4': 'print("__main__\'s locals:", locals())'}
In [5]: foo()
calling foo...
foo's globals: {'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'sys', 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'print("__main__\'s globals:", globals())', 'print("__main__\'s locals:", locals())', 'foo()'], '_oh': {}, '_dh': [WindowsPath('C:/Users/Administrator')], 'In': ['', 'sys', 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'print("__main__\'s globals:", globals())', 'print("__main__\'s locals:", locals())', 'foo()'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x000002C52E64CD90>>, 'exit': <IPython.core.autocall.ExitAutocall object at 0x000002C52E648910>, 'quit': <IPython.core.autocall.ExitAutocall object at 0x000002C52E648910>, 'open': <function open at 0x000002C52D4DC220>, '_': '', '__': '', '___': '', '_i': 'print("__main__\'s locals:", locals())', '_ii': 'print("__main__\'s globals:", globals())', '_iii': 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', '_i1': 'sys', '_i2': 'def foo():\n print(\'calling foo...\')\n a_string = \'bar\'\n a_int = 42\n print("foo\'s globals:", globals())\n print("foo\'s locals:", locals())\n ', 'foo': <function foo at 0x000002C52E9BBE20>, '_i3': 'print("__main__\'s globals:", globals())', '_i4': 'print("__main__\'s locals:", locals())', '_i5': 'foo()'}
foo's locals: {'a_string': 'bar', 'a_int': 42}
6, 包
包是一个有层次的文件目录结构,是由子包和模块组成
子包的同级目录中,需要有个__init__.py文件,该文件的作用是初始化模块
6-1, 导入包
和导入模块的方法相同,使用from-import来导入包
包也使用据点属性来访问他们的元素
from package.module import *
这样的语句会导入那些文件取决于操作系统的文件系统,所以我们在__init__.py中加入__all__变量,该变量包含执行这样的语句时,应该导入的模块名字,它有一个模块名字符串列表组成
6-2, 绝对导入和相对导入
在导入子包前加上句点,表示是相对导入,导入的方式只能是from-import方式
# Analog前的.表示是相对导入的意思
# Analog与当前py文件存在同一层级
from .Analog import dial
# common_util的第一个点表示相对导入的意思
# 第二个句点,表示从上层目录导入, 即common_util模块或子包在当前py文件的上层目录中
from ..common_util import setup
7, 阻止属性导入
若要阻止某个模块的属性导入,则可以在该属性名使用_xx(属性名前一个下划线)形式
若是导入了整个模块或是显示导入该属性,则该方法不起作用
# 这时不能导入Analog模块中的_dail属性
from Phone.Mobile.Analog import *
print('args:', dail, _dail)
# 这时能导入Analog模块中的_dail属性
from Phone.Mobile.Analog import _dail
print('args:', dail, _dail)
8, 循环导入
在A模块中导入B,在B模块中导入A,这种情况就会上报错误
解决循环导入的方法,把其中的一个导入引入到函数中进行导入;因为导入模块是执行的顶层代码,函数中的导入不会执行,所以能解决循环导入的问题
# a1.py
from a import b
# a2.py
from b import a