翼度科技»论坛 编程开发 python 查看内容

day09-函数高级

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
1.函数嵌套

python中以函数为作用域,在作用域中定义的相关数据只能被当前作用域或子作用域使用。
  1. NAME = "武沛齐"
  2. print(NAME)
  3. def func():
  4.     print(NAME)
  5. func()
复制代码
1.1 函数在作用域中

其实,函数也是定义在作用域中的数据,在执行函数时候,也同样遵循:优先在自己作用域中寻找,没有则向上一接作用域寻找,例如:
  1. # 1. 在全局作用域定义了函数func
  2. def func():
  3.     print("你好")
  4. # 2. 在全局作用域找到func函数并执行。
  5. func()
  6. # 3.在全局作用域定义了execute函数
  7. def execute():
  8.     print("开始")
  9.     # 优先在当前函数作用域找func函数,没有则向上级作用域中寻找。
  10.     func()
  11.     print("结束")
  12. # 4.在全局作用域执行execute函数
  13. execute()
复制代码
此处,有一个易错点:作用域中的值在被调用时到底是啥?

  • 情景1
    1. def func():
    2.     print("你好")
    3. func()
    4. def execute():
    5.     print("开始")
    6.     func()
    7.     print("结束")
    8. execute()        # 打印你好
    9. def func():
    10.     print(666)
    11. func()
    复制代码
  • 情景2
    1. def func():
    2.     print("你好")
    3. func()
    4. def execute():
    5.     print("开始")
    6.     func()
    7.     print("结束")
    8. def func():
    9.     print(666)
    10. func()
    11. execute()        # 打印666
    复制代码
1.2 函数定义的位置

上述示例中的函数均定义在全局作用域,其实函数也可以定义在局部作用域,这样函数被局部作用域和其子作用域中调用(函数的嵌套)。
  1. def func():
  2.     print("沙河高晓松")
  3. def handler():
  4.     print("昌平吴彦祖")
  5.     def inner():
  6.         print("朝阳大妈")
  7.     inner()
  8.     func()
  9.     print("海淀网友")
  10. handler()
复制代码
到现在你会发现,只要理解数据定义时所存在的作用域,并根据从上到下代码执行过程进行分析,再怎么嵌套都可以搞定。
现在的你可能有疑问:为什么要这么嵌套定义?把函数都定义在全局不好吗?
其实,大多数情况下我们都会将函数定义在全局,不会嵌套着定义函数。不过,当我们定义一个函数去实现某功能,想要将内部功能拆分成N个函数,又担心这个N个函数放在全局会与其他函数名冲突时(尤其多人协同开发)可以选择使用函数的嵌套。
  1. def f1():
  2.     pass
  3. def f2():
  4.     pass
  5. def func():
  6.     f1()
  7.     f2()
复制代码
  1. def func():
  2.     def f1():
  3.         pass
  4.     def f2():
  5.         pass
  6.     f1()
  7.     f2()
复制代码
  1. """
  2. 生成图片验证码的示例代码,需要提前安装pillow模块(Python中操作图片的一个第三方模块)
  3.         pip3 install pillow
  4. """
  5. import random
  6. from PIL import Image, ImageDraw, ImageFont
  7. def create_image_code(img_file_path, text=None, size=(120, 30), mode="RGB", bg_color=(255, 255, 255)):
  8.     """ 生成一个图片验证码 """
  9.     _letter_cases = "abcdefghjkmnpqrstuvwxy"  # 小写字母,去除可能干扰的i,l,o,z
  10.     _upper_cases = _letter_cases.upper()  # 大写字母
  11.     _numbers = ''.join(map(str, range(3, 10)))  # 数字
  12.     chars = ''.join((_letter_cases, _upper_cases, _numbers))
  13.     width, height = size  # 宽高
  14.     # 创建图形
  15.     img = Image.new(mode, size, bg_color)
  16.     draw = ImageDraw.Draw(img)  # 创建画笔
  17.     def get_chars():
  18.         """生成给定长度的字符串,返回列表格式"""
  19.         return random.sample(chars, 4)
  20.     def create_lines():
  21.         """绘制干扰线"""
  22.         line_num = random.randint(*(1, 2))  # 干扰线条数
  23.         for i in range(line_num):
  24.             # 起始点
  25.             begin = (random.randint(0, size[0]), random.randint(0, size[1]))
  26.             # 结束点
  27.             end = (random.randint(0, size[0]), random.randint(0, size[1]))
  28.             draw.line([begin, end], fill=(0, 0, 0))
  29.     def create_points():
  30.         """绘制干扰点"""
  31.         chance = min(100, max(0, int(2)))  # 大小限制在[0, 100]
  32.         for w in range(width):
  33.             for h in range(height):
  34.                 tmp = random.randint(0, 100)
  35.                 if tmp > 100 - chance:
  36.                     draw.point((w, h), fill=(0, 0, 0))
  37.     def create_code():
  38.         """绘制验证码字符"""
  39.         if text:
  40.             code_string = text
  41.         else:
  42.             char_list = get_chars()
  43.             code_string = ''.join(char_list)  # 每个字符前后以空格隔开
  44.         # Win系统字体
  45.         # font = ImageFont.truetype(r"C:\Windows\Fonts\SEGOEPR.TTF", size=24)
  46.         # Mac系统字体
  47.         # font = ImageFont.truetype("/System/Library/Fonts/SFNSRounded.ttf", size=24)
  48.         # 项目字体文件
  49.         font = ImageFont.truetype("MSYH.TTC", size=15)
  50.         draw.text([0, 0], code_string, "red", font=font)
  51.         return code_string
  52.     create_lines()
  53.     create_points()
  54.     code = create_code()
  55.     # 将图片写入到文件
  56.     with open(img_file_path, mode='wb') as img_object:
  57.         img.save(img_object)
  58.     return code
  59. code = create_image_code("a2.png")
  60. print(code)
复制代码
1.3 嵌套引发的作用域问题

基于内存和执行过程分析作用域。
  1. name = "武沛齐"
  2. def run():
  3.     name = "alex"
  4.     def inner():
  5.         print(name)
  6.     inner()
  7. run()
复制代码
  1. name = "武沛齐"
  2. def run():
  3.     name = "alex"
  4.     def inner():
  5.         print(name)
  6.     return inner
  7. v1 = run()
  8. v1()
  9. v2 = run()
  10. v2()
复制代码
  1. name = "武沛齐"
  2. def run():
  3.     name = "alex"
  4.     def inner():
  5.         print(name)
  6.     return [inner,inner,inner]
  7. func_list = run()
  8. func_list[2]()
  9. func_list[1]()
  10. funcs = run()
  11. funcs[2]()
  12. funcs[1]()
复制代码

三句话搞定作用域:

  • 优先在自己的作用域找,自己没有就去上级作用域。
  • 在作用域中寻找值时,要确保此次此刻值是什么。
  • 分析函数的执行,并确定函数作用域链。(函数嵌套)
练习题


  • 分析代码,写结果
    1. name = '武沛齐'
    2. def func():
    3.     def inner():
    4.         print(name)
    5.     res = inner()
    6.     return res
    7. v = func()        # 打印武沛齐
    8. print(v)        # None
    复制代码
  • 分析代码,写结果
    1. name = '武沛齐'
    2. def func():
    3.      def inner():
    4.         print(name)
    5.         return "alex"
    6.      res = inner()
    7.      return res
    8. v = func()        # 打印武沛齐
    9. print(v)        # alex
    复制代码
  • 分析代码,写结果
    1. name = 'root'
    2. def func():
    3.     def inner():
    4.         print(name)
    5.         return 'admin'
    6.     return inner
    7. v = func()        # v=inner
    8. result = v()        # 打印root
    9. print(result)        # admin
    复制代码
  • 分析代码,写结果
    1. def func():
    2.     name = '武沛齐'
    3.     def inner():
    4.         print(name)
    5.         return '路飞'
    6.     return inner
    7. v11 = func()
    8. data = v11()        # 打印武沛齐
    9. print(data)        # 路飞
    10. v2 = func()()        # 打印武沛齐
    11. print(v2)        # 路飞
    复制代码
  • 分析代码,写结果
    1. def func(name):
    2.     # name="alex"
    3.     def inner():
    4.         print(name)
    5.         return 'luffy'
    6.     return inner
    7. v1 = func('武沛齐')()        # 打印武沛齐
    8. print(v1)        # luffy
    9. v2 = func('alex')()        # 打印alex
    10. print(v2)        # luffy
    复制代码
  1. def func(name):
  2.     def inner():
  3.         print(name)
  4.         return 'luffy'
  5.     return inner
  6. v1 = func('武沛齐')
  7. v2 = func('alex')
  8. v1()        # 打印武沛齐
  9. v2()        # 打印alex
复制代码


  • 分析代码,写结果
  1. def func(name=None):
  2.     if not name:
  3.         name= '武沛齐'
  4.     def inner():
  5.         print(name)
  6.         return 'root'
  7.     return inner
  8. v1 = func()()        # 打印武沛齐
  9. v2 = func('alex')()        # 打印alex
  10. print(v1,v2)        # v1=root,v2=root
复制代码

2.闭包

闭包,简而言之就是将数据封装在一个包(区域)中,使用时再去里面取。(本质上 闭包是基于函数嵌套搞出来一个中特殊嵌套)

  • 闭包应用场景1:封装数据防止污染全局。
    1. name = "武沛齐"
    2. def f1():
    3.     print(name, age)
    4. def f2():
    5.     print(name, age)
    6. def f3():
    7.     print(name, age)
    8. def f4():
    9.     pass
    复制代码
    1. def func(age):
    2.     name = "武沛齐"
    3.     def f1():
    4.         print(name, age)
    5.     def f2():
    6.         print(name, age)
    7.     def f3():
    8.         print(name, age)
    9.     f1()
    10.     f2()
    11.     f3()
    12. func(123)
    复制代码
  • 闭包应用场景2:封装数据封到一个包里,使用时在取。

  1. def task(arg):
  2.     def inner():
  3.         print(arg)
  4.     return inner
  5. v1 = task(11)
  6. v2 = task(22)
  7. v3 = task(33)
  8. v1()
  9. v2()
  10. v3()
复制代码
  1. def task(arg):
  2.     def inner():
  3.         print(arg)
  4.     return inner
  5. inner_func_list = []
  6. for val in [11,22,33]:
  7.     inner_func_list.append( task(val) )
  8. inner_func_list[0]() # 11
  9. inner_func_list[1]() # 22
  10. inner_func_list[2]() # 33
复制代码
  1. """ 基于多线程去下载视频 """
  2. from concurrent.futures.thread import ThreadPoolExecutor
  3. import requests
  4. def download_video(url):
  5.     res = requests.get(
  6.         url=url,
  7.         headers={
  8.             "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
  9.         }
  10.     )
  11.     return res.content
  12. def outer(file_name):
  13.     def write_file(response):
  14.         content = response.result()
  15.         with open(file_name, mode='wb') as file_object:
  16.             file_object.write(content)
  17.     return write_file
  18. POOL = ThreadPoolExecutor(10)
  19. video_dict = [
  20.     ("东北F4模仿秀.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0300f570000bvbmace0gvch7lo53oog"),
  21.     ("卡特扣篮.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f3e0000bv52fpn5t6p007e34q1g"),
  22.     ("罗斯mvp.mp4", "https://aweme.snssdk.com/aweme/v1/playwm/?video_id=v0200f240000buuer5aa4tij4gv6ajqg")
  23. ]
  24. for item in video_dict:
  25.     future = POOL.submit(download_video, url=item[1])
  26.     future.add_done_callback(outer(item[0]))
  27. POOL.shutdown()
复制代码

3.装饰器

现在给你一个函数,在不修改函数源码的前提下,实现在函数执行前和执行后分别输入 "before" 和 "after"。
  1. def func():
  2.     print("我是func函数")
  3.     value = (11,22,33,44)
  4.     return value
  5. result = func()
  6. print(result)
复制代码
3.1 第一回合

你的实现思路:
  1. def func():
  2.     print("before")
  3.     print("我是func函数")
  4.     value = (11,22,33,44)
  5.     print("after")
  6.     return value
  7. result = func()
复制代码
我的实现思路:
  1. def func():
  2.     print("我是func函数")
  3.     value = (11, 22, 33, 44)
  4.     return value
  5. def outer(origin):
  6.     def inner():
  7.         print('inner')
  8.         origin()
  9.         print("after")
  10.     return inner
  11. func = outer(func)
  12. result = func()
复制代码
处理返回值:
  1. def func():
  2.     print("我是func函数")
  3.     value = (11, 22, 33, 44)
  4.     return value
  5. def outer(origin):
  6.     def inner():
  7.         print('inner')
  8.         res = origin()
  9.         print("after")
  10.         return res
  11.     return inner
  12. func = outer(func)
  13. result = func()
复制代码
3.2 第二回合

在Python中有个一个特殊的语法:在某个函数上方使用@函数名,
@函数名
def xxx():
pass
则python内部会自动执行函数名(xxx),执行完之后,再将结果赋值给xxx
  1. def outer(origin):
  2.     def inner():
  3.         print('inner')
  4.         res = origin()
  5.         print("after")
  6.         return res
  7.     return inner
  8. @outer
  9. def func():
  10.     print("我是func函数")
  11.     value = (11, 22, 33, 44)
  12.     return value
  13. func()
复制代码
3.3 第三回合

请在这3个函数执行前和执行后分别输入 "before" 和 "after"
  1. def func1():
  2.     print("我是func1函数")
  3.     value = (11, 22, 33, 44)
  4.     return value
  5. def func2():
  6.     print("我是func2函数")
  7.     value = (11, 22, 33, 44)
  8.     return value
  9. def func3():
  10.     print("我是func3函数")
  11.     value = (11, 22, 33, 44)
  12.     return value
  13. func1()
  14. func2()
  15. func3()
复制代码
你的实现思路:
  1. def func1():
  2.     print('before')
  3.     print("我是func1函数")
  4.     value = (11, 22, 33, 44)
  5.     print("after")
  6.     return value
  7. def func2():
  8.     print('before')
  9.     print("我是func2函数")
  10.     value = (11, 22, 33, 44)
  11.     print("after")
  12.     return value
  13. def func3():
  14.     print('before')
  15.     print("我是func3函数")
  16.     value = (11, 22, 33, 44)
  17.     print("after")
  18.     return value
  19. func1()
  20. func2()
  21. func3()
复制代码
我的实现思路:
  1. def outer(origin):
  2.     def inner():
  3.         print("before 110")
  4.         res = origin()  # 调用原来的func函数
  5.         print("after")
  6.         return res
  7.     return inner
  8. @outer
  9. def func1():
  10.     print("我是func1函数")
  11.     value = (11, 22, 33, 44)
  12.     return value
  13. @outer
  14. def func2():
  15.     print("我是func2函数")
  16.     value = (11, 22, 33, 44)
  17.     return value
  18. @outer
  19. def func3():
  20.     print("我是func3函数")
  21.     value = (11, 22, 33, 44)
  22.     return value
  23. func1()
  24. func2()
  25. func3()
复制代码
装饰器,在不修改原函数内容的前提下,通过@函数可以实现在函数前后自定义执行一些功能(批量操作会更有意义)。
优化

优化以支持多个参数的情况。
  1. def outer(origin):
  2.     def inner(*args, **kwargs):
  3.         print("before 110")
  4.         res = origin(*args, **kwargs)  # 调用原来的func函数
  5.         print("after")
  6.         return res
  7.     return inner
  8. @outer  # func1 = outer(func1)
  9. def func1(a1):
  10.     print("我是func1函数")
  11.     value = (11, 22, 33, 44)
  12.     return value
  13. @outer  # func2 = outer(func2)
  14. def func2(a1, a2):
  15.     print("我是func2函数")
  16.     value = (11, 22, 33, 44)
  17.     return value
  18. @outer  # func3 = outer(func3)
  19. def func3(a1):
  20.     print("我是func3函数")
  21.     value = (11, 22, 33, 44)
  22.     return value
  23. func1(1)
  24. func2(11, a2=22)
  25. func3(999)
复制代码
其中,我的那种写法就称为装饰器。

  • 实现原理:基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内层函数),执行函数时再在内层函数中执行闭包中的原函数。
  • 实现效果:可以在不改变原函数内部代码 和 调用方式的前提下,实现在函数执行和执行扩展功能。
  • 适用场景:多个函数系统统一在 执行前后自定义一些功能。
  • 装饰器示例
    1. def outer(origin):
    2.     def inner(*args, **kwargs):
    3.         # 执行前
    4.         res = origin(*args, **kwargs)  # 调用原来的func函数
    5.         # 执行后
    6.         return res
    7.     return inner
    8. @outer
    9. def func():
    10.     pass
    11. func()
    复制代码
伪应用场景

在以后编写一个网站时,如果项目共有100个页面,其中99个是需要登录成功之后才有权限访问,就可以基于装饰器来实现。
  1. pip3 install flask
复制代码
基于第三方模块Flask(框架)快速写一个网站:
  1. from flask import Flask
  2. app = Flask(__name__)
  3. def index():
  4.     return "首页"
  5. def info():
  6.     return "用户中心"
  7. def order():
  8.     return "订单中心"
  9. def login():
  10.     return "登录页面"
  11. app.add_url_rule("/index/", view_func=index)
  12. app.add_url_rule("/info/", view_func=info)
  13. app.add_url_rule("/login/", view_func=login)
  14. app.run()
复制代码
基于装饰器实现的伪代码:
  1. from flask import Flask
  2. app = Flask(__name__)
  3. def auth(func):
  4.     def inner(*args, **kwargs):
  5.         # 在此处,判断如果用户是否已经登录,已登录则继续往下,未登录则自动跳转到登录页面。
  6.         return func(*args, **kwargs)
  7.     return inner
  8. @auth
  9. def index():
  10.     return "首页"
  11. @auth
  12. def info():
  13.     return "用户中心"
  14. @auth
  15. def order():
  16.     return "订单中心"
  17. def login():
  18.     return "登录页面"
  19. app.add_url_rule("/index/", view_func=index, endpoint='index')
  20. app.add_url_rule("/info/", view_func=info, endpoint='info')
  21. app.add_url_rule("/order/", view_func=order, endpoint='order')
  22. app.add_url_rule("/login/", view_func=login, endpoint='login')
  23. app.run()
复制代码
重要补充:functools

你会发现装饰器实际上就是将原函数更改为其他的函数,然后再此函数中再去调用原函数。
  1. def handler():
  2.     pass
  3. handler()
  4. print(handler.__name__) # handler
复制代码
  1. def auth(func):
  2.     def inner(*args, **kwargs):
  3.         return func(*args, **kwargs)
  4.     return inner
  5. @auth
  6. def handler():
  7.     pass
  8. handler()
  9. print(handler.__name__) # inner
复制代码
  1. import functools
  2. def auth(func):
  3.     @functools.wraps(func)
  4.     def inner(*args, **kwargs):
  5.         return func(*args, **kwargs)
  6.     return inner
  7. @auth
  8. def handler():
  9.     pass
  10. handler()
  11. print(handler.__name__)  # handler
复制代码
其实,一般情况下大家不用functools也可以实现装饰器的基本功能,但后期在项目开发时,不加functools会出错(内部会读取__name__,且__name__重名的话就报错),所以在此大家就要规范起来自己的写法。
  1. import functools
  2. def auth(func):
  3.     @functools.wraps(func)        # inner.__name__=func.__name__,inner.__doc__=func.__doc__
  4.     def inner(*args, **kwargs):
  5.         """巴巴里吧"""
  6.         res = func(*args, **kwargs)  # 执行原函数
  7.         return res
  8.     return inner
复制代码
总结


  • 函数可以定义在全局、也可以定义另外一个函数中(函数的嵌套)
  • 学会分析函数执行的步骤(内存中作用域的管理)
  • 闭包,基于函数的嵌套,可以将数据封装到一个包中,以后再去调用。
  • 装饰器

    • 实现原理:基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内层函数),执行函数时再在内层函数中执行闭包中的原函数。
    • 实现效果:可以在不改变原函数内部代码 和 调用方式的前提下,实现在函数执行和执行扩展功能。
    • 适用场景:多个函数系统统一在 执行前后自定义一些功能。
    • 装饰器示例
      1. import functools
      2. def auth(func):
      3.     @functools.wraps(func)
      4.     def inner(*args, **kwargs):
      5.         """巴巴里吧"""
      6.         res = func(*args, **kwargs)  # 执行原函数
      7.         return res
      8.     return inner
      复制代码

练习


  • 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:执行func时,先执行func函数内部代码,再输出 "after"
    1. def func(a1):
    2.     return a1 + "傻叉"
    3. def base(a1,a2):
    4.     return a1 + a2 + '傻缺'
    5. def foo(a1,a2,a3,a4):
    6.     return a1 + a2 + a3 + a4 + '傻蛋'
    复制代码
    1. import functools
    2. def dec(origin):
    3.     @functools.wraps(origin)
    4.     def inner(*args, **kwargs):
    5.         res = origin(*args, **kwargs)
    6.         print("after")
    7.         return res
    8.     return inner
    9. @dec
    10. def func(a1):
    11.     return a1 + "傻叉"
    12. @dec
    13. def base(a1, a2):
    14.     return a1 + a2 + '傻缺'
    15. @dec
    16. def foo(a1, a2, a3, a4):
    17.     return a1 + a2 + a3 + a4 + '傻蛋'
    18. func("1")
    19. base("1", "2")
    20. foo("1", "2", "3", "4")
    复制代码
  • 请为以下所有函数编写一个装饰器,添加上装饰器后可以实现:将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。
    1. import random
    2. def func():
    3.     return random.randint(1,4)
    4. result = func() # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result
    5. print(result)
    复制代码
    1. import random
    2. import functools
    3. def dec(origin):
    4.      @functools.wraps(origin)
    5.      def inner(*args, **kwargs):
    6.          data_list = []
    7.          for i in range(5):
    8.              res = origin(*args, **kwargs)
    9.              data_list.append(res)
    10.          return data_list
    11.      return inner
    12. @dec
    13. def func():
    14.      return random.randint(1, 4)
    15. result = func()  # 内部自动执行5次,并将每次执行的结果追加到列表最终返回给result
    16. print(result)
    复制代码
  • 请为以下函数编写一个装饰器,添加上装饰器后可以实现: 检查文件所在路径(文件件)是否存在,如果不存在自动创建文件夹(保证写入文件不报错)。
    1. def write_user_info(path):
    2.     file_obj = open(path, mode='w', encoding='utf-8')
    3.     file_obj.write("武沛齐")
    4.     file_obj.close()
    5. write_user_info('/usr/bin/xxx/xxx.png')
    复制代码
    1. import functools
    2. import os
    3. def check(origin):
    4.     @functools.wraps(origin)
    5.     def inner(path):
    6.         # 获取上级路径
    7.         folder_path = os.path.dirname(path)
    8.         if not os.path.exists(folder_path):
    9.             os.makedirs(folder_path)
    10.         res = origin(path)
    11.         return res
    12.      
    13.     return inner
    14. @check
    15. def write_user_info(path):
    16.     file_obj = open(path, mode='w', encoding='utf-8')
    17.     file_obj.write("武沛齐")
    18.     file_obj.close()
    19. write_user_info('files/xxx.png')
    复制代码
  • 分析代码写结果:
    1. def get_data():
    2.     scores = []
    3.     def inner(val):
    4.         scores.append(val)
    5.         print(scores)
    6.     return inner
    7. func = get_data()
    8. func(10)        # [10]
    9. func(20)        # [10, 20]
    10. func(30)        # [10, 20, 30]
    复制代码
  • 看代码写结果
    1. name = "武沛齐"
    2. def foo():
    3.     print(name)
    4. def func():
    5.     name = "root"
    6.     foo()
    7. func()        # 武沛齐
    复制代码
  • 看代码写结果
    1. name = "武沛齐"
    2. def func():
    3.     name = "root"
    4.     def foo():
    5.         print(name)
    6.     foo()
    7. func()        # root
    复制代码
  • 看代码写结果
    1. def func(val):
    2.     def inner(a1, a2):
    3.         return a1 + a2 + val
    4.     return inner
    5. data_list = []
    6. for i in range(10):
    7.     data_list.append(  func(i)   )
    8. print(data_list)        # [<function func.<locals>.inner at 0x0000024AB7733280>, <function func.<locals>.inner at 0x0000024AC82E63A0>, <function func.<locals>.inner at 0x0000024AC82E6550>, <function func.<locals>.inner at 0x0000024AC8BF5940>, <function func.<locals>.inner at 0x0000024AC8BF59D0>, <function func.<locals>.inner at 0x0000024AC8BF5A60>, <function func.<locals>.inner at 0x0000024AC8BF5AF0>, <function func.<locals>.inner at 0x0000024AC8BF5B80>, <function func.<locals>.inner at 0x0000024AC8BF5C10>, <function func.<locals>.inner at 0x0000024AC8BF5CA0>]
    复制代码
  • 看代码写结果
    1. def func(val):
    2.     def inner(a1, a2):
    3.         return a1 + a2 + val
    4.     return inner
    5. data_list = []
    6. for i in range(10):
    7.     data_list.append(func(i))
    8. v1 = data_list[0](11,22)
    9. v2 = data_list[2](33,11)
    10. print(v1)        # 33
    11. print(v2)        # 46
    复制代码

来源:https://www.cnblogs.com/sbhglqy/p/18114137
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具