函数对象、名称空间和作用域、闭包函数、装饰器

导读:本篇文章讲解 函数对象、名称空间和作用域、闭包函数、装饰器,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一、函数对象:
  函数名就相当于变量名,把函数的内存地址当作一种变量值(一种数据类型)去使用
  在面向对象编程中,一切皆对象
  具体的体现:
    1.函数可以被引用
    2.函数可以作为函数的参数
    3.函数可以作为函数的返回值
    4.函数可以存储到容器类型中

二、函数嵌套:
  1.嵌套定义
  def outer():
    def inner():
    pass
  2. 嵌套调用
  def max2(x, y):
    if x > y:
      return x
    else:
      return y

  def max4(a, b, c, d):
    res1 = max2(a.b)
    res2 = max2(res1, c)
    res3 = max2(res2, d)
    return res3

三、名称空间和作用域
名称空间:
  1.什么是名称空间:
    存放名字与值内存地址绑定关系的地方
    x=10
    x:10的内存地址

  2.为什么要有名称空间:

  3.如何用内存空间:
    内置名称空间:存放py解释器自带的函数名称
      parcharm解释器启动时创建,关闭解释器时销毁

    全局名称空间:文件级别的名称:除了内置名称和函数内名称,其余都是全局名称
      运行文件时创建,所有文件运行结束或者中途删除时销毁

    局部名称空间:函数内定义的名称
      调用函数时创建,函数执行完毕销毁

    查找名称顺序:
      1.查找名字的顺序是从当前位置往外查找
      2.名称空间的嵌套关系是在函数定义阶段就固定死的,与调用的位置没关系
      函数的作用域在定义时就固定了,与调用的位置没关系

    名称空间的加载顺序:
      内置>全局>局部
    名称空间的查找顺序:
      局部>全局>内置 (不能反着找)

作用域:
  域指的是区域、范围
    即全局范围:全局存活 全局有效
    无论在任何位置都能看的到

  全局的名称空间和内置的名称空间 在使用上没什么区别
  局部的和全局的内置的 就有区别了 局部定义的只能在局部使用

  全局的 和 内置的可以划分为同一个范围
  global 表示的是全局范围 就是所谓的全局作用域

  局部的单独一个范围
  local 局部作用域

  globals() 查看全局作用域中的内容
  locals()查看局部作用域中的内容 (相对局部,站在什么位置看就是哪个局部,
    比如你在全局作用域中使用locals,看到的就是全局作用域的内容)

 

四、闭包函数:

  1.什么是闭包函数
    闭函数:该函数一定是定义在函数内的函数
    包函数:该内部函数包含对外层函数作用域名字的引用

  2.为何要用闭包函数
    传值

  3.如何用
  为函数体传值的方案一:直接参数传
  def f():
    print(x)

  为函数体传值的方案二:闭包传值
  def outer(x):
    def f():
      print(x)
    return f

  f1 = outer(10)
  f2 = outer(11)

  f1()

  f2()

五、装饰器
  1.什么是装饰器
    装饰器指的是为被装饰对象添加新功能的工具
    装饰器本身可以是任意可调用的对象
    被装饰对象本身也可以是任意可调用对象

  2.为何要用装饰器
    开放封闭原则:对修改封闭,对扩展开放

    装饰器的原则:
      1.不能修改被装饰对象的源代码
      2.不能修改被装饰对象的调用方式

    装饰器的目的:
      就是在遵循原则1和2的前提下,为被装饰对象添加新功能

  3.如何用

    1.源函数
    def index():
      time.sleep(1)
      print(‘welcome to index page’)

    2.添加功能
    import time
    def index():
      time.sleep(1)
      print(‘welcome to index page’)

    def outer(func):
      # func=最原始那个index的内存地址
      def wrapper(*args,**kwargs):
        start_time = time.time()
        res=func(*args,**kwargs):#最原始那个index的内存地址
        end_time = time.time()
        print(‘time is %s’ %(end_time – start_time))
        return res
      return wrapper

    index=outer(index) #index=outer(最原始那个index的内存地址) index=wrapper的内存地址
    index() #wrapper的内存地址()
        # 偷梁换柱 用户并不知道

    3.语法糖
    import time
    def outer(func):
      # func=最原始那个index的内存地址
      def wrapper(*args,**kwargs):
        start_time = time.time()
        res=func(*args,**kwargs):#最原始那个index的内存地址
        end_time = time.time()
        print(‘time is %s’ %(end_time – start_time))
        return res
        return wrapper

      @outer #index=outter(index)
      def index():
        time.sleep(1)
        print(‘welcome to index page’)
      index()

    总结:

      要写一个装饰器,先定义一个新函数例如def inner():,写要添加的功能,写好之后打包。

      所谓打包其实有固定的套路,在新函数同级头下写return inner,在新函数同级头上写参数func=index(index为源函数名)

      定义一个外函数def outer():,将写好的新函数上下三行,统一缩进,打包进外函数内。就可以了

      使用语法糖,调用装饰器运行源函数即可。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/6430.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!