函数对象、名称空间和作用域、闭包函数、装饰器
一、函数对象:
	  函数名就相当于变量名,把函数的内存地址当作一种变量值(一种数据类型)去使用
      在面向对象编程中,一切皆对象
      具体的体现:
            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():,将写好的新函数上下三行,统一缩进,打包进外函数内。就可以了
使用语法糖,调用装饰器运行源函数即可。
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号