def foo(): bar() print('from foo') def bar(): print('from bar') foo() # 输出结果: from bar from foo # 注意:此处并不会报错,因为函数在定义阶段只检查语法错误,当调用foo函数的时候,bar函数已经载入到了内存中,所以即使bar的定义在foo后面,调用的时候也能找到bar的函数代码,因此能正常运行。
def 函数名(): '''函数功能注释''' # 注释 函数内代码块 return 返回值 # 非必须
def 函数名(参数1, 参数2, ...): '''函数功能注释''' # 注释 函数内代码块 return 返回值 # 非必须
def 函数名(): pass
函数名() # 方式一:无参函数调用 函数名(参数1,参数2, ...) # 方式二:有参函数调用
# 示例: # len内置函数用于计算值得长度 v1 = len("武沛齐") print(v1) # 3 # len重新定义成另外一个函数 def len(a1,a2): return a1 + a2 # 以后执行len函数,只能按照重新定义的来使用 v3 = len(1,2) print(v3)
# 示例1: def func(a1,a2): print(a1,a2) func_list = [func,func,func] func(11,22) func_list[0](11,22) func_list[1](33,44) func_list[2](55,66) # *********************** # 示例2: def func(a1,a2): print(a1,a2) # 执行func函数 func(11,22) # func重新赋值成一个字符串 func = "武沛齐" print(func)
# 示例1:做参数 def plus(num): return num + 100 def handler(func): res = func(10) # 110 msg = "执行func,并获取到的结果为:{}".format(res) print(msg) # 执行func,并获取到的结果为:110 # 执行handler函数,将plus作为参数传递给handler的形式参数func handler(plus) # *********************************************** # 示例2:做返回值 def plus(num): return num + 100 def handler(): print("执行handler函数") return plus result = handler() data = result(20) # 120 print(data)
# 示例 def send_msg(mobile, content): """发送短信""" pass def send_email(to_email, subject, content): """发送图片""" pass def send_wechat(user_id, content): """发送微信""" pass func_list = [ {"name": send_msg, "params": {'mobile': "15131255089", "content": "你有新短消息"}}, {"name": send_email, "params": {'to_email': "wupeiqi@live.com", "subject": "报警消息", "content": "硬盘容量不够用了"}}, {"name": send_wechat, "params": {'user_id': 1, 'content': "约吗"}}, ] # {"name": send_msg, "params": {'mobile': "15131255089", "content": "你有新短消息"}}, for item in func_list: func = item['name'] # send_msg param_dict = item['params'] # {'mobile': "15131255089", "content": "你有新短消息"} func(**param_dict) # send_msg(**{'mobile': "15131255089", "content": "你有新短消息"})
def func(*arg, **kwargs): print(arg, kwargs) func(3,4,5,x=66,y=77) # 输出结果: >>> (3, 4, 5) {'x':66, 'y':77}
def func(a, b, c, x, y): print(a, b, c, x, y) func(*(1,2,3), **{'x':4, 'y':5}) # 输出结果: >>> 1, 2, 3, 4, 5
def func(a, b, *args, c=9, **kwargs): print(a, b, c, args, kwargs) func(1, 2, 99, 77, x = 4, y = 5) #输出结果: >>> 1 2 9 (99, 77) {'x': 4, 'y': 5}
def func(a, b, c=9, *args, **kwargs): print(a, b, c, args, kwargs) func(1, 2, 99, 77, x = 4, y = 5) #输出结果: >>> 1 2 99 (77,) {'x': 4, 'y': 5}
函数执行传参时,传递的是内存地址。优点:
COUNTRY = "中国" CITY_LIST = ["北京","上海","深圳"] def download(): url = "http://www.xxx.com" global CITY_LIST CITY_LIST = ["河北","河南","山西"] print(CITY_LIST) global COUNTRY COUNTRY = "中华人民共和国" print(COUNTRY) def upload(): file_name = "rose.zip" print(COUNTRY) print(CITY_LIST) download() upload()
# 示例: def func(): print("沙河高晓松") def handler(): print("昌平吴彦祖") def inner(): print("朝阳大妈") inner() func() print("海淀网友") handler()
作用域链
。(函数嵌套)def func(age): name = "武沛齐" def f1(): print(name, age) def f2(): print(name, age) def f3(): print(name, age) f1() f2() f3() func(123)
def task(arg): def inner(): print(arg) return inner inner_func_list = [] for val in [11,22,33]: inner_func_list.append( task(val) ) inner_func_list[0]() # 11 inner_func_list[1]() # 22 inner_func_list[2]() # 33
from flask import Flask app = Flask(__name__) def auth(func): def inner(*args, **kwargs): # 在此处,判断如果用户是否已经登录,已登录则继续往下,未登录则自动跳转到登录页面。 return func(*args, **kwargs) return inner @auth def index(): return "首页" @auth def info(): return "用户中心" @auth def order(): return "订单中心" def login(): return "登录页面" app.add_url_rule("/index/", view_func=index, endpoint='index') app.add_url_rule("/info/", view_func=info, endpoint='info') app.add_url_rule("/order/", view_func=order, endpoint='order') app.add_url_rule("/login/", view_func=login, endpoint='login') app.run()
__name__
,且__name__
重名的话就报错),所以在此大家就要规范起来自己的写法。import functools def auth(func): @functools.wraps(func) def inner(*args, **kwargs): """原函数执行前需要执行的代码""" res = func(*args, **kwargs) # 执行原函数 """原函数执行后需要执行的代码""" return res return inner
lambda x: 函数体 lambda x1,x2: 函数体 lambda *args, **kwargs: 函数体
func = lambda x: x + 100 v1 = func(10) print(v1) # 110
def func(data): return data.replace("苍老师","***") func= lambda data: data.replace("苍老师","***")
func = lambda x: "大了" if x > 66 else "小了" v1 = func(1) print(v1) # "小了" v2 = func(100) print(v2) # "大了"
定义:生成器是由函数+yield关键字创造出来的写法,在特定情况下,用他可以帮助我们节省内存。
def func(): print(111) yield 1 print(222) yield 2 print(333) yield 3 print(444) data = func() # 执行生成器函数func,返回的是生成器对象。 # 注意:执行生成器函数时,函数内部代码不会立刻执行。
生成器对象的调用
def func(): print(111) yield 1 print(222) yield 2 print(333) yield 3 print(444) data = func() v1 = next(data) print(v1) v2 = next(data) print(v2) v3 = next(data) print(v3) v4 = next(data) print(v4) # 结束或中途遇到return,程序爆:StopIteration 错误
data = func() for item in data: print(item)
def func(): print(111) v1 = yield 1 print(v1) print(222) v2 = yield 2 print(v2) print(333) v3 = yield 3 print(v3) print(444) data = func() n1 = data.send(None) print(n1) n2 = data.send(666) print(n2) n3 = data.send(777) print(n3) n4 = data.send(888) print(n4)
应用场景举例:
假设要让你生成 300w个随机的4位数,并打印出来。
import random val = random.randint(1000, 9999) print(val)
import random data_list = [] for i in range(300000000): val = random.randint(1000, 9999) data_list.append(val) # 再使用时,去 data_list 中获取即可。 # ...
import random def gen_random_num(max_count): counter = 0 while counter < max_count: yield random.randint(1000, 9999) counter += 1 data_list = gen_random_num(3000000) # 再使用时,去 data_list 中获取即可。
总结:所以,当以后需要我们在内存中创建很多数据时,可以想着用基于生成器来实现一点一点生成(用一点生产一点),以节省内存的开销。
函数被调用过程中:
# 内存中创建空间存储 [1, 2] ,假设内存地址为:10000001 def func(a1, a2=[1, 2]): a2.append(a1) return a2 # 未给默认值参数传值,a1=10 # a2 -> 10000001 # v1 -> 10000001 # 执行完成后,10000001地址的值为 [1, 2, 10] v1 = func(10) # 未给默认值参数传值,a1=20 # a2 -> 10000001 # v2 -> 10000001 # 执行完成后,10000001地址的值为 [1, 2, 10, 20] v2 = func(20) # 给默认值参数传值[11, 22],假设内存地址为11111110,a1=30 # a2 -> 11111110 [11,22,30] # v3 -> 11111110 # 执行完成后,11111110 值为[11, 22, 30] , 10000001 值仍为[1, 2, 10, 20] v3 = func(30, [11, 22]) # 未给默认值参数传值,a1=40 # a2 -> 10000001 # v4 -> 10000001 # 执行完成后,10000001 值为[1, 2, 10, 20, 40] v4 = func(40) # 执行到此处,v1、v2、v4都指向10000001的内存地址,因此值都为 # [1, 2, 10, 20, 40],v3指向新开辟的内存地址 11111110,因此值为 [11,22,30]。 print(v1) # [1, 2, 10, 20, 40] print(v2) # [1, 2, 10, 20, 40] print(v3) # [11,22,30] print(v4) # [1, 2, 10, 20, 40]
python函数思维导图:
清晰版请下载:python基础-思维导图-函数