函数
2020-09-27 10:46:18 0 举报
AI智能生成
登录查看完整内容
函数的思维导图及生成器的运行原理与关键字
作者其他创作
大纲/内容
函数
函数的调用以及返回值
函数的结构
def 函数名():\t函数体def 关键字 定义一个函数函数名与变量名设置规则相同,要具有可描述性,多个单词组成一定是用下划线。小括号:里面设置形参。一个函数式一个功能。
函数的返回值
一个函数代表一个功能,执行完毕这个功能,总会得到一个结果。真假,最终的结算结果或者是None等等。
关键字return
函数中遇到return直接终止函数
def func(): print(111) print(222) print(333) return print(444) print(555)func()
函数可以给函数的执行者(函数名())返回值
只写return后面什么都不写或者不写return返回值都是None
def func(): a = 1 b = 2 # returnret = func()print(ret)
返回单个值。不会改变返回值的数据类型
返回多个值,一定是以元组的形式返回多个值
函数的调用
函数名()调用一个函数,只有执行到了函数名()才会执行此函数里面的代码。遇到一次,执行一次
def len_(argv): count = 0 for i in argv: count += 1 print(count)len_(s1)len_(s1)len_(s1)len_(s1)
作用域
全局作用域
内置名称空间与全局名称空间
局部作用域
临时命名空间
globals
获取的是全局作用域(截止到此行代码之前)的所有的变量与值的对应关系
name = 'barry'a = 100def func(): name = '太白' b = 200print(globals()) print(locals())c = 666\"\"\
locals
当前作用域内(截至到此行代码之前)变量与值的对应关系
name = 'barry'a = 100def func(): name = '太白' b = 200 print(globals()) print(locals()) # 当前作用域内(截止到此行代码之前)变量与值的对应关系func()
global、nonlocal
global
在局部声明一个全局变量
def func(): global name name = 'barry'# 测试1print(globals())print(name)func()# 测试2:func()print(globals())print(name)
在局部可以更改一个全局变量
name = '太白'def func(): global name name = 'barry'print(name)func()print(name)
注意!!!局部修改全局变量有坑:可变的数据类型。只要,局部空间修改了全局的变量的指向关系,就会报错,无论是不是可变的数据类型。
nonlocal
不能操作全局变量
def func(): # 不能操作全局变量 nonlocal a a = 6566func()
在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的那层,从那层及以下此变量全部发生改变
def func(): a = 1 def inner(): nonlocal a a = 666 print(a) inner() print(a)func()
格式化输出
语法
可以加入任意表达式
可执行函数
换行字符串
name = 'barry'age = 30hobby = '工作,挣奶粉钱'home = '保定's5 = f\"\"\"我是{name},今年{age},老家{home}\"\"\"print(s5)name = 'barry'age = 18ajd = 'handsome'speaker = f'Hi {name}.\'\\ f'You are {age} years old.\'\\ f'You are a {ajd} guy!'print(speaker)
注意点
迭代器
定义
字面解释
一个可以重复取值的一个工具
专业角度
实现了无参数的next方法,返回序列中的下一个元素,如果没有元素了,那么抛出StopIteration异常。python中的迭代器还实现了iter方法,因此迭代器也可以迭代如果一个对象内部含有iter以及next方法,那么他就是迭代器
判断一个对象是否是迭代器
可迭代对象转化迭代器
通过iter或者__iter__()
通过next方法对迭代器进行取值
# 通过next方法取值# iterator1.__next__()print(next(iterator1))print(next(iterator1))print(next(iterator1))print(next(iterator1))print(next(iterator1))print(next(iterator1)) # 报错 StopIteration
利用while循环模拟for循环一个可迭代对象的原理
小结
迭代器的优点
节省内存
如果是含有上百万元素的列表,占内存就上百空间,但是含有上百万元素的迭代器,占内存只是一个空间
惰性机制。next一次,取一个值,绝不过多取值
迭代是数据处理的基石。扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式
缺点
操作方法少。只能使用next
取值时不能走回头路,只能一直向下取值
不能直观数据
迭代器与可迭代对象对比
可迭代对象
是一个私有的方法比较多,操作灵活(比如列表。字典的增删改查,字符串的常用操作方法),比较直观,但是 占内存而且不能直接通过循环迭代取值的这么一个数据集
应用
当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择
是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集
当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选元素时,将数据集设置为迭代器是一个不错的选择(可参考python为什么把文件句柄设置成迭代器)
列表的推导式与生成器表达式
跌表推导式
解释
一行代码构建一个有规律的列表
# 循环模式[变量(加工后的变量) for 变量 in iterable]# 筛选模式[变量(加工后的变量) for 变量 in iterable if 条件]
循环模式
print([i*i for i in range(11)])print([i**2 for i in range(11)])
筛选模式
过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
列表推导式只能构建较为复杂的有规律的列表,不能构建所有的列表。
一般如果循环超过3层,就不要用列表推导式了。
列表推导式有毒,慎重使用。
生成器表达式
生成器表达式与列表推导式构建的方式一模一样,也有循环模式以及筛选模式。只有一点不同。它是用小括号括起来并且形成的结果是生成器。
生成器与可迭代对象的转化
可迭代对象转化成生成器(迭代器)
iter(iterable)
生成器转化成可迭代对象 (也是对生成器进行取值的方式)
转化成可迭代对象
print(list(obj))
生成器表达式和列表推导式的区别:
列表推导式一目了然,生成器表达式只是一个内存地址。
无论是生成器表达式,还是列表推导式,他只是Python给你提供了一个相对简单的构造方式,因为使用推导式非常简单,所以大多数都会为之着迷,这个一定要深重,推导式只能构建相对复杂的并且有规律的对象,对于没有什么规律,而且嵌套层数比较多(for循环超过三层)这样就不建议大家用推导式构建。
生成器的惰性机制:
其他的推导式
字典推导式
集合推导式
函数的参数
实参角度
位置参数
按照从左至右 的顺序,与形参一一对应。
关键字参数
实参的关键字参数一定要与形参的参数一一对应
混合参数
位置参数一定要在关键字参数前面,一一对应
形参角度
形参角度的位置参数与实参角度的位置参数一样,从左至右一一对应
默认值参数
一般我们把经常使用的数据设置成默认值参数。不给默认值参数传值,则沿用默认值,如果给默认值参数传值则覆盖默认值。
三元运算
变量1 = 变量2(数值) if 条件 else 变量3(数值)
万能参数
动态参数,将实参角度所用的位置参数以及关键字参数全部接受
聚合
函数定义时,*代表聚合 一颗星会将实参角度所有的位置参数聚合成元组赋值给args 函数定义时,*代表聚合 两颗星会将实参角度所有的关键字参数聚合成字典赋值给kwargs
打散
函数的执行时,*代表打散,*dict会将字典里面的所有键值对打散成关键字参数函数的执行时,*代表打散,*iterable 会将可迭代对象里面的所有的元素打散成位置参数
形参的顺序
*的使用
函数中,定义时代表聚合;函数的执行时代表打散。
*可以处理剩余元素。
最终顺序:位置参数,*args,默认值参数,**kwargs.
仅限关键字参数
3.5之后的更新。这个参数一定是放在*args的后面的最终顺序:位置参数,*args,仅限关键字参数,默认值参数,**kwargs.
函数式编程:函数式编程是面向过程式编程的一种升级,本质还是面向过程式编程。一个函数封装了一个功能。
名称空间
当程序运行时,整个py文件会创建一个全局名称空间,存储整个py文件变量与值得对应关系当函数执行时,会在内存中创建一个临时命名空间,存储此函数内部的变量与值对应关系,随着函数的结束而消失内置命名空间:当程序运行时,会在内存中产生一个内置名称空间,存储内置的函数、模块等变量与值得对应关系。
全局命名空间
我们直接在py文件中,函数外声明的变量都属于全局命名空间
局部命名空间
在函数中声明的变量会放在局部命名空间
内置命名空间
存放python解释器为我们提供的名字,list、tuple、str、int这些都是内置命名空间
加载顺序与取值顺序
加载顺序
当程序运行时先加载内置名称空间--->全局名称空间--->函数执行时 临时名称空间
取值顺序
全局名称空间寻找变量 先从全局找,全局没有再从内置空间找就近原则
input = 666# print(input)def func1(): input = 777 print(input)func1()
满足就近原则如果你是在局部名称空间寻找变量:不可逆局部名称空间--->全局名称空间--->内置名称空间
高阶函数
引子
列表,字典都可以嵌套很多的列表,字典,函数里面也可以嵌套函数,一般不超过三层。一般考察的就是执行顺序
例子
# # 例1:def func1(): print('in func1') # 1 print(3) # 2def func2(): print('in func2') # 4 print(4) # 5func1()print(1) # 3func2()print(2) # 6# # 例2:def func1(): print('in func1') # 3 print(3) # 4def func2(): print('in func2') # 2 func1() print(4) # 5print(1) # 1func2()print(2) # 6# # 例3:def fun2(): print(2) # 2 def fun3(): print(6) # 4 print(4) # 3 fun3() print(8) # 5print(3) # 1fun2()print(5) # 6
函数名的使用
函数名的本质就是变量
函数名指向的数据就是函数的内存地址
def func(): print('in func')print(func) # <function func at 0x00000259EB5A5048>func()a = 1b = ac = bprint(c)f1 = funcf2 = f1f3 = f2f3()
函数名可以作为容器类类型的元素
函数名可以作为函数的实参
def func1(): print('in func1')def func2(f): # f= func1 f() # func1() print('in func2')a = 666func2(a)func2(func1)
函数名可以作为函数的返回值
def func1(): print('in func1')def func2(f): print('in func2') return f # func1内存地址ret = func2(func1) # func1内存地址ret()
如果一个对象里面含有多个数据,可迭代对象,(不准确)
字面意思
什么是对象
python中一切皆对象,str、bool、dict、函数、文件句柄
什么是可迭代对象
更新迭代,必须可以一个一个去执行,并且每次执行的结果稍有不同
总结
一个可以重复取值的实实在在的东西(内容数据 等等)
获取一个对象内部所有的方法
内置函数dir
s1 = 'barry'i = 100# strprint(dir(s1))print(dir(i))
判断一个对象是否可迭代
print('__iter__' in dir(s1))print('__iter__' in dir(tuple))print('__iter__' in dir(list))print('__iter__' in dir(dict))print('__iter__' in dir(bool))
优点
可迭代对象内容直观,操作速度快操作方法多
占内存可迭代对象不可以直接取值(除去索引与键以外)
生成器
可以生成数据的工具。生成器与迭代器很多人都认为是一种。生成器与迭代器如果要找到唯一的不同:迭代器都是python的内置函数或者其他的功能(文件句柄)或者由可迭代对象转化得来的(iter())。而生成器就是我们自己通过python代码构建的。
构建方式
生成器函数
def func(): print(111) yield 666 print(2222) print(3333) yield 'barry'gen_obj = func()# print(gen_obj) # 生成器对象print(next(gen_obj))print(next(gen_obj))
return vs yield
return结束函数,并且给函数的执行者返回值,一个函数中一般直设置一个return
yield不会结束函数,给next返回值,一个生成器函数可以设置多个yield
next
yield from
补充
函数的传参实际上是变量的赋值运算的过程
内置函数
本节我们讲内置函数。 首先来说,函数就是以功能为导向,一个函数封装一个功能,那么Python将一些常用的功能(比如len)给我们封装成了一个一个的函数,供我们使用,他们不仅效率高(底层都是用C语言写的),而且是拿来即用,避免重复早轮子,那么这些函数就称为内置函数,到目前为止python给我们提供的内置函数一共是68个,由于时间关系以及考虑这些函数的不同重要性我们会挑常用的重要的内置函数去讲,就是下面红色黄色背景的内置函数,剩下的内置函数你们参照着我的博客自己课下练习一下即可。
一带而过
all() any() bytes() callable() chr() complex() divmod() eval() exec() format() frozenset() globals() hash() help() id() input() int() iter() locals() next() oct() ord() pow() repr() round()
重点讲解
abs() enumerate() filter() map() max() min() open() range() print() len() list() dict() str() float() reversed() set() sorted() sum() tuple() type() zip() dir()
未来会讲
classmethod() delattr() getattr() hasattr() issubclass() isinstance() object() property() setattr() staticmethod() super()
eval执行字符串里面的代码(有返回值)
慎用:如果数据来源不明(通过网络得来的或者客户输入的指令),不要使用。
exec 执行字符串类型的代码(代码流没有返回值)。
s1 = \"\"\"for i in range(3): print(i)\"\"\"# exec(s1)
hash 得到不可变的数据的哈希值。
help:函数用于查看函数或模块用途的详细说明。
import time# print(help(str))print(help(time))
callable:函数用于检查一个对象是否是可调用的。如果返回True,object仍然可能调用失败;但如果返回False,调用对象ojbect绝对不会成功。
a = 666def func(): passprint(callable(a))print(callable(func))
int 构建数字。
将字符串或者bool值转化为数字
float:函数用于将整数和字符串转换成浮点数。
a = 3print(float(a))
complex:函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。。
bin:将十进制转换成二进制并返回。
oct:将十进制转化成八进制字符串并返回。
hex:将十进制转化成十六进制字符串并返回。
round 保留浮点数的小数位数,默认保留整数。
pow:求x**y次幂 。
bytes:用于不同编码之间的转化。
ord:输入字符找该字符编码的位置
print(ord('a')) # asciiprint(ord('魍')) # utf-8
chr:输入位置数字找出其对应的字符
print(chr(65)) # Aprint(chr(34234)) # 薺
repr 返回一个对象的string形式(原形毕露)。
name = '马达'msg = '达哥的小名:%r' %(name)print(msg)
all:可迭代对象中,全都是True才是True
any:可迭代对象中,有一个True 就是True
0 条评论
回复 删除
下一页