函数
- 模块
模块: 一个py文件就是一个模块, 每个模块之间是可以相互访问的 访问之前需要进行导入
分类: 1.系统提供的模块 math random
2.自己自定义的,自己封装的常用功能的的py文件
3.第三方模块需要进行安装。安装格式: pip install 三方模块名
导入:1. import 模块名 ;使用:模块名.内容
import random;random.randint(1, 100)
2. from 模块 import 具体某个内容
from random import randint;使用:randint(1, 100)
3. 通配符*导入 泛指该模块中所有的内容
from 模块名 import *
- 包
包:类比成计算机中的文件夹,一个个的文件夹就是在对计算机中的内容进行分类整理的 方便于查找东西。
计算机中的文件不允许重名,就想保存两个重名的文件,把他们放在不同的文件夹中
作用:对模块进行分类管理。给模块提供了多级命名空间。有了包之后,导入该包下面的模块。导入方式: import 一级包名.二级包名....n级包名.模块名
程序中建包:右键建立包的位置-- new -- python package;建完包之后 包中有一个__init__.py文件。
作用:向解释器解释类似于计算机中文件夹的是一个项目的包 不是一个普通文件夹。
普通的文件夹 没有再程序中为模块提供多级命名空间的作用。不同的普通文件夹中 模块不能相互访问
- 程序入口设定
程序入口:完成一个程序 需要几个py文件配合才能完成程序的运行。需要给一个标记 让别人知道到底是从哪个 文件开始启动执行的
在启动执行的文件中加一个if判断。判断__name__的值,如果是起始文件 __name__的值就等于 __main__;如果不是 __name__ 的值他对应的模块名
判断格式:if __name__ == "__main__":启动文件的执行内容
可变参函数
可变参数
有一种需求,在封装功能的时候并不能确定到底有多少个未知项参与功能运算 也就无法确定声明函数时形参个数。
把这个参数设置可变参数 ---> 使用一个形参接受多个实参 ---> 这个形参在函数中是容器[元组来存放的]
声明可变参数的格式
def 函数名(*变量名, 形参1,.., 形参n):
功能的运算
return 结果 # 没有结果返回 此句可省
1 """ 2 求n个数的累加和。将型参封装为可变参数 3 """ 4 def nums_sum(*num): 5 print(num) 6 ''' 7 结果是元组容器:(12, 34, 56, 74, 86) 8 也可以接收实参是 元组、列表、集合等类型。 9 但是直接传递一个容器过来,会当作一个元素存在元组中。 10 若想传递成功,需要让实参和型参等价。即实参加*号 11 ''' 12 total = 0 13 for ele in num: 14 total += ele 15 return total 16 if __name__ == '__main__': 17 res = nums_sum(12,34,56,74,86) 18 print(res) 19 20 tuple0 = (77,45,86,34,23,23) 21 res = nums_sum(*tuple0) # 让实参和型参等价。即实参加*号 22 print(res)
关键字参数
关键字参数
调用者调用函数的时候可以传入0个或者多个带有形参名的关键字参数
为了避免形参多的情况下传递实参的顺序不太确定,可以传递实参的时候采用:
函数名(形参名=实参, 形参名=实参)
这种是根据形参名找到对应的形参为其赋值,不用担心顺序的问题
命名
调用者可以传入 形参名中没有设定 关键字参数 到底传入什么数据 需要在函数中进行判定:
例如
必填项 ---> 已知形参
选填项 ---> 可以使用命名关键字参数 接收时的格式:形参名=实参
声明方式:
接受调用者传递的位置的关键字数据时 在函数中是通过字典来接受的
1 def accept(name,password,**kwargs): 2 print(kwargs) # 结果:{'sex': '女', 'city': '北京'} 3 if 'city' in kwargs: 4 print("用户的居住地:",kwargs['city']) 5 if 'sex' in kwargs: 6 print("用户的性别:", kwargs['sex']) 7 if __name__ == '__main__': 8 accept("yaya","123456",sex="女",city='北京',) 9 10 dict0 = { 'a':97,'b':78} # 也可以穿入字典类型,加**符号 11 accept("pepe",'123456',**dict0)
匿名函数
匿名函数:生成函数一种简单方式 ---> 简单函数封装的简化。匿名函数执行一次就释放掉
使用要求:函数功能中只有一个return语句就能结束函数的这种形式可以简化成匿名函数
声明格式:lambda 形参1,形参2, .., 形参n : 功能的结果[功能的结果只能使用一句代码表示]
使用场景:对一般型参中接收函数时,可以使用匿名函数来进行传递。这样比传递一个参数是带名函数节省方法池的内存
1 def add(a, b): 2 return a + b 3 """等价于""" 4 lambda a, b : a + b
1 # 对一般型参中接收函数时,可以使用匿名函数来进行传递。这样比传递一个参数是带名函数节省方法池的内存 2 list0 = [-19,33,54,75] 3 max_value = max(list0,key=lambda n:-n) 4 print(max_value) 5 # 要求是根据字典中年龄对列表进行降序排序 6 person_list = [{ 'name':'Tom','age':23},{ 'name':'Lili','age':45},{ 'name':'Susan','age':32}] 7 person_list.sort(key=lambda p_dict:p_dict['age']) 8 print(person_list)
偏函数
偏函数:偏函数是对原本存在的函数的一种修改。借助偏函数 对使用场景比较多的函数进行修改来满足场景的需求
自定义一个方法 间接执行原本设计的方法
使用系统提供的 funstools模块有一个方法可以转换对方法默认值的使用
1 # 原来使用 2 print('a',end='\t') 3 print('a',end='\t') 4 5 # 自定义可变参数 6 def cus_print(*value): 7 print(*value,end='......') 8 # 再次使用时 9 cus_print('a','b') 10 cus_print('c','d') 11 12 # 系统提供的方法 13 import functools 14 func = functools.partial(print, end="!!!!") 15 func('good')
闭包
闭包:
1 # 闭包 2 def outer(): 3 print('外部函数') 4 def inner(): 5 print('内部函数') 6 # 只能在外部函数中调用inner 7 inner() 8 outer()
装饰器
参考下一篇笔记 :https://www.cnblogs.com/TMMM/p/11395710.html
生成器
生成器 :
根据逻辑生成一个存放数据的容器。弥补了列表生成式的弊端。
生成器节省了内存,当生成器产生的时候 数据不会立即存放在内存中,而是取出一个存放一个
与列表生成式的区别:
生成器有两种方式生成数据:
将列表生成式的中括号换成小括号(生成的数据 数据的来源 对数据的进行筛选)
类似于方法的声明 需要每次调用方法的时候需要返回生成的数据 。不是使用return 返回 [因为return直接结束函数] 使用yield代替return返回生成器中的数据
1 # 生成器的第一种方式生成和获取数据 2 ge = (num for num in range(1,1000)) 3 print(ge) # 其类型 结果:at 0x106b9c480> 4 value = next(ge) 5 print(value) # 结果是:1。再次执行next(ge),结果是:2 6 # 获取前10个数据 7 for _ in range(10): 8 value = next(ge) 9 print(value) 10 ''' 11 遍历的时候 需要将对应的值赋予给变量 就得起一个变量的名字来存放数据 12 遍历的时候 只是为了获取循环的次数,为不会获取序列中的元素 就可以使用_占位符变量 13 ''' 14 15 # 生成器的第二种方式生成和获取数据 16 def get_value(): 17 for i in range(1,1000): 18 yield i # 此处并非结束函数,如果在yield后面还有平级的语句是会被执行的,但是是在第二次获取的时候执行 19 ge = get_value() 20 print(ge) # 其类型 结果:at 0x106b9c480> 21 value = next(ge) 22 print(value)
注意: 当生成其中的数据取完之后,再去取数据,就回报错
迭代器
迭代器:是相当于另外一种遍历序列的方式,通过next方法一个一个进行迭代 移动取数据的。如果一个序列想使用迭代器 前提这个序列是可以迭代的
1 from collections import Iterable,Iterator 2 3 # 验证指定数据是否是可迭代类型的 4 res = isinstance(10,Iterable) 5 print(res) # 结果 :False。 整型是不可以迭代的 6 7 res = isinstance('10',Iterable) 8 print(res) # 结果 :True。字符串类型是可以迭代的 9 10 res = isinstance(('10'),Iterable) 11 print(res) # 结果 :True。元组类型是可以迭代的 12 13 res = isinstance(['10'],Iterable) 14 print(res) # 结果 :True。列表类型是可以迭代的 15 16 res = isinstance({ '10'},Iterable) 17 print(res) # 结果 :True。集合类型是可以迭代的 18 19 res = isinstance({ '10':10},Iterable) 20 print(res) # 结果 :True。字典类型是可以迭代的 21 """ 22 Iterable 这个类型验证的结果是:所有的序列都是可以迭代的[遍历],for in 进行遍历 23 能用for in进行遍历的序列,不一定能用迭代器进行遍历。迭代器遍历使用next方法一个一个迭代的 24 生成器 --- 可以使用next来迭代 --- 就可以使用迭代器迭代。 25 列表 --- 可以使用for in进行遍历 --- 但不能使用迭代器迭代 26 """ 27 28 # 若想使用迭代器进行迭代列表类型,需要使用iter(序列)进行转换, 29 # 转化成Iterator迭代器的类型才可以使用next方法进行遍历迭代 30 list0 = [12,34,64,76,34,5,86] 31 it = iter(list0) 32 value = next(it) 33 print(value) # 结果:12 34 value = next(it) 35 print(value) # 结果:34