函数嵌套>作用域>闭包函数

一:函数对象

函数是第一类对象,即表示函数可以当做数据传递

可以被引用:把函数内存地址赋值给一个变量名,仍然遵循函数的调用规则。

可以被当做参数传递:传递的是函数的运行的结果#可以当做返回值 把函数作为返回值返回的话,返回的结果是函数的内存地址。

可以当做容器类型的元素:意思就是可以作为列表和字典的元素利用函数的特性,可以取代多分枝的if。

示例:

def auth():
    print("登陆......")

def register():
    print("注册.......")

def seach():
    print("查看........")

dic = {
    "1": auth,
    "2": register,
    "3": seach,
    }

def interactive():
    while True:
        msg = """
        1 登陆 
        2 注册
        3 查看
        """
        print(msg)
        choice = input("请输入选择:").strip()
        if choice not in dic:
            print("没有该功能编号")
            continue
        else:
            dic[choice]()

interactive()
View Code

二:函数的嵌套

函数的嵌套调用:在函数中调用了其他函数

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

def max3(x, y, z):
    res1 = max2(x, y)
    res2 = max2(res1, z)
    return res2

print(max3(11, 199, 2))

函数的嵌套定义:

  在函数中定义其他函数。

  函数的嵌套定义只能在定义的同一级别调用。

def func1():
    print("weqwewq")

def func2():        # 在函数func1中定义func2
    print("dsadas")
    print(func2)    # 打印函数地址
    print(func2())  # 运行函数,打印函数的返回值
    func2()         # 运行函数,print("dsadas")

func1()

嵌套函数调用

def f1():
    print("f1")

def f2():
    print("f2")

def f3():
    print("f3")

def f4():
    print("f4")

f4()
f3()
f2()
f1()

三:名称空间与作用域

什么是名称空间

名称空间有内置名称空间、全局名称空间、局部名称空间,名称空间存放着名字与值的绑定关系:
  内置名称空间存放python字自带的名字,内置的名字在解释器启动时生效,在解释器关闭后失效;
  全局名称空间存放文件级别的名字,要求是顶头写的:如全局变量、函数名等,全局的名字在文件执行的时候生效,在文件结束或文件执行期间被删除的时候失效;
  局部名称空间存放在函数内定义的名字(函数内的参数和函数内的名字),在函数调用时生效,在函数调用结束时候失效;

名称空间的加载顺序

  内置名称空间》》全局名称空间》》局部名称空间

  在全局无法查看到局部的名称,但是在局部却可以查看全局的名称

四:作用域

作用域即范围

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

  局部范围:函数调用时存活,调用结束时失效,局部有效

作用域关系在函数定义阶段就已经固定,与函数的调用位置没有关系

def f1():           # 定义函数f1
    def f2():       # 嵌套定义函数f2
        print(x)    # 打印变量x的值
    return f2       # 返回函数f2的内存地址

x = 100             # 定义全局变量 x = 100

def f3(func):       # 定义函数f3
    x = 2           # 定义局部变量x=2,其作用域仅在函数f3内有效
    func()          # 执行传给的函数

x= 10000            # 再次定义一个全局变量x=10000,该全局变量覆盖了上一个,x=100全局变量已经失效

f3(f1())

函数f3(f1()) 执行,首先调用函数f1,定义函数f2,在定义阶段函数f2中x的作用域是全局范围,所以获取的是全局变量x的值,得到返回的函数f2的内存地址,把其内存地址当做实参传递给函数f3,调用函数f3,局部变量x=2无效,于是输出x的值10000。

五:闭包函数

闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
应用领域:延迟计算
利用闭包函数封装一个request请求

from urllib.request import urlopen
def index(url):
    def get():
        return urlopen(url).read()
    return get

baidu = index('http://www.baidu.com')
print(baidu().decode('utf-8'))

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

提示:之前我们都是通过参数将外部的值传给函数,闭包提供了另外一种思路。

def counter():
    n = 0
    def incr():
        nonlocal n
        x = n
        n += 1
        return x
    return incr

c = counter()
print(c())
print(c())
print(c())
print(c.__closure__[0].cell_contents)
posted @ 2018-03-28 19:03  Leslie-x  阅读(279)  评论(0编辑  收藏  举报