1. python函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。
2. 定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
2.任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
3.函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
4.函数内容以冒号起始,并且缩进。
5.return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
调用函数
函数名加()
实例1:函数不加()打印出来的是内存地址
def a():
print(1)
print(a)
<function a at 0x02F4B618>
实例2:
def test(name,age):
print('名字:',name)
print('年龄:',age)
return
test('lzb',18)
名字: lzb
年龄: 18
3. 实参和形参
定义函数括号里的一般叫形参
调用时括号里传递的参数一般叫实参
实例:
def student(age):
print('my age is %s' % age)
student(18)
age是型参,18是实参
4. 参数的具体应用
4.1 位置参数:按照从左到右的顺序定义的参数
位置形参:必选参数
位置实参:按照位置给形参传值
实例:
def a(x,y):
print(x,y)
a(1,2)
1 2
4.2 关键字参数:按照key=value的形式定义的实参,无需按照位置为形参传值。
注意的问题:1. 关键字实参必须在位置实参右面 2. 对同一个形参不能重复传值
实例:
def a(x,y):
print(x,y)
a(y=2,x=1)
1 2
4.3 默认参数:形参在定义时就已经为其赋值,可以传值也可以不传值,经常需要变得参数定义成位置形参,变化较小的参数定义成默认参数(形参)。
注意的问题:
1. 只在定义时赋值一次
2. 默认参数的定义应该在位置形参右面
3. 默认参数通常应该定义成不可变类型
实例:
def a(x,y=2):
print(x,y)
a(4)
4 2
def a(x,y=2):
print(x,y)
a(4,5)
4 5
4.4 可变长参数:可变长指的是实参值的个数不固定,而实参有按位置和按关键字两种形式定义,针对这两种形式的可变长,形参对应有两种解决方案来完整地存放它们,分别是*argsh和**kwargs
*args:传递的参数会变成元组
实例:
def a(x,y,*args):
print(x,y,args)
a(1,2,3,4,5)
1 2 (3, 4, 5)
**kwargs:传递的参数会变成字典
实例:
def a(x,y,**kwargs):
print(x,y,kwargs)
a(1,2,a=4,b=4,c=4)
1 2 {'a': 4, 'b': 4, 'c': 4}
5. return语句,可以返回任意数据类型
return语句[表达式]退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
6. 函数的特性
6.1 函数可以被引用
def f1():
print('this is f1')
return 'ok'
res = f1()
print(res)
6.2 函数可以当参数传递
def s1(a):
print(a)
def s2(b):
print(b)
s2(s1('测试'))
测试
None
6.3 嵌套函数
7. 名称空间和作用域
内置名称空间:(python启动时就有)python解释器内置的名字,比如print,max,min
全局名称空间:(执行python文件时启动,顶格写的)定投定义的变量,在if,while语句中的也属于全局。
局部名称空间:(调用函数时启动,调用结束失效)函数内部定义的变量
三者的加载顺序:内置--->全局--->局部
三者的访问顺序:局部--->全局--->内置
8. 装饰器
在不修改源代码和调用方式的基础上给其增加新的功能,多个装饰器可以装饰在同一个函数上
实例1:没有参数的装饰器
def deco(func):
def wrapper():
func() #func()=func1()
print('this is new ')
return wrapper
@deco #func1=wrapper func=func1
def func1():
print('this is ok')
# func1=deco(func1) 这句等效于@deco
func1() #wrapper()
输出结果如下:
this is ok
this is new
这时this is new作为新的功能被添加到func1上
实例2:有参数的装饰器
def deco(func):
def wrapper(x,y):
func(x,y) #func()=func1()
print('this is new ')
return wrapper
@deco #func1=wrapper func=func1
def func1(x,y):
print('this is ok')
print(x)
print(y)
# func1=deco(func1) 这句等效于@deco
func1(1,2) #wrapper()
输出结果如下:
this is ok
1
2
this is new
9. 迭代器
特点:迭代是一个重复的过程,即每一次重复为一次迭代,并且每次迭代的结果都是下一次迭代的初始值。
为何要有迭代器?
对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。
但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,
则必须找出一种不依赖于索引的迭代方式,这就是迭代器。
str1 = 'hello,world'
l1 = ['a','b','c']
t1 = ('a','b','c')
info = {
'name':'程泽宇',
'age':23
}
s1 = {1,2,3,3,5,9}
f = open('a.txt','r',encoding='utf-8')
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,如字符串,列表,字典,集合,元组
整数,浮点数都不是可迭代对象
str1.__iter__()
l1.__iter__()
t1.__iter__()
info.__iter__()
s1.__iter__()
f.__iter__()
可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
而迭代器对象指的是即内置有__iter__又内置有__next__方法的对象
f.__iter__()
f.__next__()
iter(l1)等效于l1.__iter__()
把一个可迭代对象变成迭代器对象iter
res=iter(l1)
此时,可以打印出他里面的数值
print(res.__next__())
print(res.__next__())
print(res.__next__())
a
b
c
next(res)等效于res.__next__()
用while循环可以实现调用所有的数值
i=0
while i<len(l1):
print(next(res))
i+=1
a
b
c
for循环最为简单实用、
for i in l1: #可迭代对象s1变成了迭代器对象iter(s1),#2.过滤错误
print(i)
总结:
1)可迭代对象包含迭代器。
2)如果一个对象拥有__iter__方法,其是可迭代对象;如果一个对象拥有next方法,其是迭代器。
3)定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__和next方法。可迭代对象不一定是迭代器对象,迭代器对象一定是可迭代对象
10. 生成器
只要函数里有yield关键字,那么函数名()得到的结果就是生成器,并且不会执行函数内部代码。生成器就是迭代器。
return和yield区别:
return只能返回一个值
yield可以返回多个值,同一时间只能存储一个值;缺点:没有索引,不能后退取值
实例:
return方式:
def b():
l=[]
for i in range(5):
l.append(i)
return l
print(b()[3])
取出第三个数字
yield方式:
def b():
for i in range(5):
yield i
for i in b():
print(i)
print()
res=iter(b())
print(next(res))
print(next(res))
print(next(res))
0
1
2
3
4
0
1
2
11. 匿名函数
匿名函数的定义lambda,自带return
匿名函数通常只调用一次,之后不在使用
print((lambda x,y:x+y)(1,2))
3
lambda的使用场景:
1. max
info={
'a':100,
'b':200,
'c':500,
'd':400,
}
print(max(info)) #打印出key最大的value
d
打印出val最大的key
第一种方法:
def func(k):
return info[k]
print(max(info,key=func))
c
第二种:
print(max(info,key=lambda k:info[k]))
C
2.排序 sorted
info={
'a':100,
'b':200,
'c':500,
'd':400,
}
以key对应的value排序顺序列出对应的key
print(sorted(info,key=lambda k:info[k]))
['a', 'b', 'd', 'x']
print(sorted(info,key=lambda k:info[k],reverse=True)) #倒序排列
['x', 'd', 'b', 'a']
3.拉链 zip
l1 = [1,2,3,4]
l2 = ['a','b','c']
print(list(zip(l1,l2)))
[(1, 'a'), (2, 'b'), (3, 'c')]
4. 映射 map
names = ['zhao','wu','du']
第一种:
l1=[]
for name in names:
res='%s_SB' % name
l1.append(res)
print(l1)
['zhao_SB', 'wu_SB', 'du_SB']
第二种:
print(list(map(lambda name:'%s_SB' %name,names)))
['zhao_SB', 'wu_SB', 'du_SB']
5. 过滤 filter
names = ['zhao_sb', 'wu_sb', 'du_sb','li']
print(list(filter(lambda i: i.endswith('_sb'),names)))
['zhao_sb', 'wu_sb', 'du_sb']
print(list(filter(lambda i: not i.endswith('_sb'),names)))
['li']
10. 内置函数(len,in,not in)
10.1 len统计长度
a={'name':'李白','age':24}
print(len(a))
b=['a','b','c']
print(len(b))
2
3
10.2 in 在....里面,有则true,无则false
print('e'in 'hello')
print('s'in 'hello')
True
False
10.3 not in 不在.....里面,没有则true,有则false
print('e'not in 'hello')
print('s'not in 'hello')
False
True