函数对象

一.函数是第一类对象,即函数可以当作数据传递

1.可以被引用

2.可以当作参数传递

3.返回值可以是函数

4.可以当作容器类型的元素

二.利用该特性,优雅的取代多分支的if

def foo():
  print('foo')
   
def bar():
  print('bar')
   
dic = {
  'foo':foo,
  'bar':bar,
}
while True:
  choice = input('输入:').strip()
  if choice in dic:
      dic[choice]()

二.函数嵌套

1.函数的嵌套调用 (调用函数必须有返回值)

def max(x,y):
  return x if x > y else y

def max4(a,b,c,d):
  res1 = max(a,b)
  res2 = max(res1,c)
  res3 = max(res2,d)
  return res3
print(max4(1,2,3,4))

2.函数的嵌套定义

def f1():
  def f2():
      def f3():
          print('from f3')
      f3()
  f2()
f1()

f3() '''遵循先定义后引用,执行函数的过程是,
      先将函数作为文本文件加载到内存,但是
      在调用之前函数内的代码都是普通的文本
      无语法意义,所以在此处调用f3()会报错,
      因为f3()还没有被定义
          '''

三.名称空间与作用域

一.什么是名称空间?

名称空间:存放名字的地方,三种名称空间(之前遗留的问题x = 1, 1存放于内存中,那么名字x存放在南里呢?

名称空间正是存放名字x与1绑定关系的地方)

二.名称空间的加载顺序

python test.py

1.python解释器先启动,因而首先加载的是:内置名称空间

2.执行test.py文件,当然以文件为基础,加载全局名称空间

3.在执行文件的过程中如果调用函数,则临时产生局部名称空间

三.名字的查找顺序

需要注意的是:在全局无法查看局部的,在局部可以查看全局的

# max = 1
def f1():
  # max = 2
  def f2():
      # max =3
      print(max)
  f2()
f1()
print(max)

四.作用域

1.作用域即范围

-全局范围(内置名称空间与全局名称空间属于该范围): 全局存活,全局有效

-局部范围(局部名称空间属于该范围):临时存活,局部有效

2.作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下

x = 1
def f1():
  def f2():
      print(x)
  return f2
# x = 100
def f3(func):
  x = 2
  func()

x = 10000
f3(f1())
'''
在这里调用函数,即把def f3()这段代码块放在了这里运行
在func()的位置传入了由f1()得到的f2的返回值,加括号运行
x在函数内找不到x就会去外层找,找不到就一直推到全局,
x = 10000覆盖了之前的定义,所以结果是10000,
x = 2是定义在f3的局部作用域里,所以在f2里是不能找到
x = 2的
'''

五.global与nonlocal关键字

申明作用域

四.闭包函数

一.什么是闭包函数

内部函数包含对外部作用域而非全局作用域的引用

首先闭值的是封闭修改,包则指的是包含外部作用域的引用

例:

def outter():
  x = 1
  def inner():
      print(x)
  return inner
f1 = outter()
x = 110
f1()

 

   def counter():                   # 定义一个包函数
          n=0 # 定义在外部的值
          def incr(): # 定义一个闭函数
              nonlocal n # 申明作用域
              x=n # 定义x = n
              n+=1 # n += 1
              return x # 得到x的返回值
          return incr # 得到incr的返回值,即函数体运行的过程,加()可以调用
           
  c=counter() # 这里定义的c,相当于定义c 等于函数counter()运行
  print(c()) # 的结果,即incr的返回值
  print(c()) # 加括号调用
  print(c())
  print(c.__closure__[0].cell_contents) #查看闭包的元素

二.闭包的意义与应用

1.返回函数对象,不仅仅是一个函数对象,在该海曙外还包裹了一层作用域,这使得,该函数

无论在何处被调用,优先使用自己外层包裹的作用域

2.应用领域:延迟计算

posted on 2019-01-14 14:49  张跃翔  阅读(131)  评论(0编辑  收藏  举报