函数定义和使用:
def 函数名(形参列表):
函数体
[return [返回值]]
查看Python中所有的关键字(33个)
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
形参列表:
a,b,c
addr='BeiJing'
可变参数:
*args -> 在函数中以元组的形式组织的
**kwargs -> 在函数中以字典形式组织的
def f1(name,addr='BeiJing',*args,**kwargs):
print(name,addr,args,kwargs)
# 不推荐使用,addr默认值参数起不到作用.
def f2(name,*args,addr='BeiJing',**kwargs):
print(name,addr,args,kwargs)
f2('Andy',1,2,3,addr='tianjin',email='abc@abc.com')
函数的使用:
使用返回值:
直接打印:print(add(1,2))
把一个函数的调用,当成另一个函数的参数
sum(add(1,2),add(3,4))
不使用返回值:单独调用:直接函数名(参数),不关心函数的返回值.
函数名当成函数的返回值:
通常发生在函数嵌套定义中:
def outer():
def inner():
....
return inner # 返回内层函数的定义,是一个地址
函数是一等公民!
函数的地位和变量一样,可以当成参数传递,可以给变量赋值.
高阶函数
可以接收一个函数作为参数的函数,称为高阶函数.
def func(f): # 当f是一个函数时,func就称为高阶函数.
pass
Python中常见的高阶函数:
map(key=)
filter(key=)
sorted(key=)
lst=[-1,2,-3,4]
def f(x):
return abs(x)
# res = map(f,lst)
# for x in res:
# print(x)
filter函数如果不指定功能参数,默认使用bool(x)操作每一个元素!用以获取一个布尔值.
def f2(x):
if x > 0:
return True
elif x < 0:
return False
f = filter(f2,lst)
for x in f:
print(x)
为了替换高阶函数中参数函数的繁琐定义,使用lambda表达式!!!
f = filter(lambda x:True if x >= 0 else False,lst)
lambda表达式最主要的使用场景:和高阶函数配合使用,充当高阶函数的参数!!!
lst = [2,1,5,9]
res = sorted(lst)
sorted是形成了一个新的排序后的结果,通常会赋值给一个变量.
高阶函数的替代者:推导式
列表推导式:
res = [包含了变量的表达式 for 变量 in 可迭代对象]
用来替换map函数:
前面的包含了变量的表达式就是map中的业务逻辑
可迭代对象就是map中的数据源
filter
res = [满足条件的元素 for 变量 in 可迭代对象 if条件判断]
filter业务逻辑使用if来实现
数据源来自可迭代对象
推导式种类:
列表推导式:
[]
字典推导式
{:}
集合推导式
{}
没有元组推导式,用()括起来的是:生成器表达式.
如何查看一个包,类中所有可用的方法(属性):
[x for x in dir(json) if not x.startswith('_')]
[x for x in dir(os) if not x.startswith('_')]
[x for x in dir(sys) if not x.startswith('_')]
[x for x in dir(time) if not x.startswith('_')]
[x for x in dir(list) if not x.startswith('_')]
[x for x in dir(tuple) if not x.startswith('_')]
[x for x in dir(set) if not x.startswith('_')]
[x for x in dir(dict) if not x.startswith('_')]
练习:把目前见到的包,常见的数据类型中可用的方法通过上述方式查到.
查看某个具体方法的使用:
help(类名) help(list)
help(类名.方法名) help(list.pop)
Python中三大神器!
迭代器:iterator
可迭代对象:iterable
从表现形式上看:能使用for循环迭代的,就是可迭代对象!
字符串,列表,字典,集合,元组.
它们都有一个方法:__iter__,魔法方法,推荐使用iter(x)
iter(x) -> 得到的是一个绑定到当前可迭代对象身上的迭代器!!!
for循环实际上干了两件事:
1.获取可迭代对象的迭代器.
2.通过迭代器遍历可迭代对象!!!
迭代器:实现了__iter__,__next__方法的对象(也称为实现了迭代器协议.),就是迭代器.
这两个方法是魔法方法(Python中不推荐直接使用的),推荐使用替代方法:
iter(x) -> 返回的就是这个迭代器本身.
next(x) -> 返回的是下一个可用元素.
lst = [1,2,3]
# 获取到迭代器对象
i = iter(lst)
# 使用迭代器的next方法,依次获取元素
print(next(i))
print(next(i))
手动使用next方法有个缺点:没有办法很好的控制边界!!!
使用for循环可以自动判定边界.
可迭代对象和迭代器的关系:
可迭代对象每次调用iter方法,获取的都是新的迭代器.
如何验证一个对象是可迭代的?还是迭代器?
from collections import Iterator,Iterable
print(isinstance([1,2,3],Iterable)) True
print(isinstance([1,2,3],Iterator)) False
生成器:generator
一种流式生成数据的方式:
流式产生数据:保存的不是真实的数据,而是产生数据的方式!!
好处:节省内存!!!!
自定义生成器(函数):
包含了yield关键字的函数,就是生成器函数.
def my_generator():
yield 10
def my_generator():
for x in range(100):
yield x
生成器本质上就是迭代器:
# 借助collections包中的Iterator类,
from collections import Iterator,Iterable
print(isinstance(g,Iterator))
# 既然是迭代器,就使用for循环迭代!!
for x in g:
print(x)
for循环本质上就是调用生成器的next方法,即:
第一种触发生成器的方式:使用next方法!!!
带有赋值语句的生成器:
第一次比较特殊:只执行一,三部分
从第二次开始:一,二,三执行.
...
第二种触发生成器的方式:使用send方法.
根据定义时是否有赋值语句,以及两种触发方式:一共有四种组合!!!
1.没有赋值语句,使用next触发
def my_generator():
for x in range(5):
yield x
g = my_generator()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
2.没有赋值语句,使用send触发
def my_generator():
for x in range(5):
yield x
g = my_generator()
print(g.send(None))
print(g.send(10))
print(g.send(20))
print(g.send(30))
由于没有变量接收,传递的值,实际上都丢弃了!!!
3.有赋值语句,使用next触发
# 有赋值语句,使用next触发
def my_generator(n):
for x in range(n+1):
n = yield x
print(n)
g = my_generator(5)
print(next(g))
print(next(g))
print(next(g))
由于没有使用send,使用next方法,实际上每次都是传递的None
4.有赋值语句,使用send触发
def my_generator(n):
total = 0
for x in range(n+1):
n = yield total
total += n
g = my_generator(5)
print(g.send(None))
print(g.send(1))
print(g.send(2))
print(g.send(3))
print(g.send(4))
计算移动平均值!
def my_generator(n):
total = 0
count = 0
avg = 0
for x in range(n+1):
n = yield avg
total += n
count += 1
avg = total / count
g = my_generator(5)
print(g.send(None))
print(g.send(10))
print(g.send(20))
print(g.send(30))
print(g.send(40))
装饰器:decorator
对原函数进行功能上的增强!
def wrapper(fn):
# return fn
# 定义嵌套函数,
def inner(*args,**kwargs):
# 对原始函数的调用
ret = fn(*args,**kwargs)
# 对原始函数的返回值进行处理
if ret < 0:
return -ret
else :
return ret
# 把嵌套函数返回
return inner
@wrapper
def func(a,b):
return a - b
print(func(5,3))
print(func(5,30))
# 定义装饰器
def w(min_value,max_value):
def wrapper(fn):
# return fn
# 定义嵌套函数,
def inner(*args,**kwargs):
# 对原始函数的调用
ret = fn(*args,**kwargs)
# 对原始函数的返回值进行处理
if ret < min_value:
return min_value
elif ret > max_value:
return max_value
# 把嵌套函数返回
return inner
return wrapper
@w(-5,5)
def fun(a,b):
return a + b