一.模块
1.模块就是python文件,后缀.py
2.为什么用模块:
- 程序太大,编写维护不方便,需要拆分
- 模块可以增加代码重复利用的方式
- 当作命名空间使用,避免命名冲突
3.如何定义模块
- 模块就是一个python文件,直接写
4.根据模块书写规范,最好在模块中编写以下内容:
- 函数(单一功能)
- 类(相似功能的组合,或类似业务模块)
- 测试代码
5.如何使用模块
- import模块直接导入
- 语法
import module_name
module_name.function_name
module_name.class_name
- 例子
#文件名(模块名):example_1
#包含一个学生类,一个函数,一个输出语句
#模块命名不能以数字开头
class Student():
def __init__(self,name = 'NoName',age = 18):
self.name = name
self.age = age
def say(self):
print('my name is {}'.format(self.name))
def sayHello():
print('hi,welcome to here')
print('我是模块example_1') #写模块时最好不要出现这种语言,会直接输出
import example_1 #相当于把模块的代码直接粘贴了过来,并且从头到尾执行了一遍,所以会先输出'我是模块example_1'
stu = example_1.Student('liu',19) #使用类
stu.say()
example_1.sayHello() #使用函数
- 模块名不能以数字开头
#借助importlib包实现导入以数字开头的模块名称
import importlib
example = importlib.import_module('01') #把01模块导入,并赋值给example
stu = example.Studennt()
stu.say()
- 模块名称太长时可以起别名
import 模块 as 别名
- 从模块中导入一个类或函数
from module_name import function_name,class_name
from example_1 import Student,sayHello
#stu = example_1.Student() #不能这么写,因为没有导入example_1模块
stu = Student() #这样写正确
stu.say()
sayHello()
- 从模块中导入所有(优点不用加模块名前缀,缺点不能防止命名污染)
from module_name import *
- 文件作为主线程时才执行该语句
#文件名(模块名):example_1
#包含一个学生类,一个函数,一个输出语句
class Student():
def __init__(self,name = 'NoName',age = 18):
self.name = name
self.age = age
def say(self):
print('my name is {}'.format(self.name))
def sayHello():
print('hi,welcome to here')
#此判断语句建议一直作为程序的入口
#可以有效避免模块代码被导入的时候被动执行的问题
if __name__ == '__main__': #当这个文件作为主线程执行时(ziji直接执行时),执行下一句,作为模块被导入时不执行
print('我是模块example_1')
二.模块的搜索路径和存储
1.什么是模块的搜索路径
- 加载模块时,系统会在哪些地方寻找此模块
2.系统默认模块搜索路径
import sys
sys.path #属性可以获取路径列表
import sys
print(type(sys.path))
print(sys.path)
for p in sys.path:
print(p)
3.添加搜索路径
sys.path.append(路径)
4.模块加载顺序
- 上搜索内存中已经加载好的模块
- 搜索python的内置模块
- 搜索sys.path路径
三.包
1.包是一种组织管理代码的方式,包里面存放的是模块,用于将模块包含在一起的文件夹就是包
2.自定义包的结构
|---包
|---|---__init__.py 包的标志文件
|---|---模块1
|---|---模块2
|---|---子包(子文件夹)
|---|---|---__init__.py 包的标志文件
|---|---|---子包模块1
|---|---|---子包模块1
四.包的导入操作
# 包名:pkg01
# 模块名:__init__、p01
#模块一:__init__
def inInit():
print("I'm in init of pkg01")
print('我在init模块中')
#模块二:p01
class Student():
def __init__(self,name = 'NoName',age = 18):
self.name = name
self.age = age
def say(self):
print('my name is {}'.format(self.name))
def sayHello():
print('hi,welcome to here')
print('我是模块p01')
1.方法一:直接导入包,此时只导入了__init__模块
- 注意此种方法是默认对__init__.py内容的导入
import package_name #直接导入一个包
import package_name as 别名 #用别名代替,功能与上句一样
- 使用方法:
package_name.func_name
package_name.class_name.func_name
- 例子
#导入包
import pkg01
pkg01.inInit()
2.方法二:导入包中的某个具体模块,此方法会默认导入__init__模块
import package_name.module_name
import package_name.module_name as 别名 #注意这个别名是包的别名而不是模块的别名
- 使用方法
package.module.function
package.module.class.function
package.module.class.var
- 例子
#导入p01模块
import pkg01.p01
stu = pkg01.p01.Student()
stu.say()
pkg01.inInit() #默认导入了__init__模块
3.方法三:from...import,从包中导入某个模块,不包含__init__模块中的内容
- 引用时可以不写包的名字
from package import module #在包中导入指定模块,引用时可以不不用写包的名字
- 例子:
from pkg01 import p01
stu = p01.Student() #引用时可以不写包的名字
stu.say()
pkg01.inInit() #报错 ,name 'pkg01' is not defined
inInit() #报错, name 'inInit' is not defined
4.方法四:from package import *
- 导入__init__模块所有内容
from package import * #从包中导入__init__模块中所有的函数和类
- 使用方法:
#不用加前缀
func_name
class_name.func_name
- 例子:
from pkg01 import *
inInit()
stu = p01.Student() #报错
stu.say()
- __all__的用法:__all__表示在使用from package import *的时候,*可以导入的内容
- __init__.py中如果文件为空(一般都为空)或者没有__all__,那么只可以把__init__中中的内容导入
- __init__.py中如果设置可__all__的值,那么按照__all__中指定的子包或者模块载入,不会载入__init__中的内容
__all__ = ['module1','module2','package1',...]
- 例子:
#__init__.py
__all__ = ['p01']
def inInit():
print('pkg02的p01')
#p01不变
#调用
from pkg01 import *
stu = p01.Student() #可以正常运行
stu.say()
inInit() #报错
5.方法五:导入包中指定模块所有内容
from package.module import *
- 用法
func_name
class_name.func_name
- 例子
from pkg01.p01 import *
stu = Student() #引用时可以不写包的名字
stu.say()
pkg01.inInit() #报错 ,name 'pkg01' is not defined
inInit() #报错, name 'inInit' is not defined
6.方法六:在当前包中导入其他模块的内容
import 完整的包或者模块路径
五.命名空间
1.用于区分不同位置不同功能但相同名称的函数或者变量的一个特定前缀
2.作用:防止命名冲突
setName()
Student.setName()
Teacher.setName() #函数或变量的所属就叫做命名空间
#不同的包、不同的模块的前缀就叫命名空间,不同的命名空间可以有相同的变量或者函数
视频参考极客学院