day05 函数的进阶

一、命名空间和作用域

  • 全局命名空间  在程序从上到下执行的过程中依次加载进内存空间,存放了我们设置的所有变量名和函数名
  • 局部命名空间  调用函数的时候才生成,函数调用结束,此处的名称空间被回收,函数内部定义的名字,
  • 内置命名空间  python解释器一启动,就可以使用的名字存储在内置命名空间中,启动解释器的时候加载到内存

局部可以使用全局、内置命名空间中的名字

全局可以使用内置命名空间中的名字,但是无法使用局部命名空间中的名字

在内置的命名空间中不能使用局部和全局的名字

正常情况下,执行内置空间中的名字

在全局定义了和内置命名空间中同名的名字时,使用全局的名字

def input():
    print("in input now")


def func():
    input()

func()  #此时func函数执行时调用的input()函数  是全局命名空间下的input()

先看自己空间是否有,如果有使用自己名称空间下的名字,如果没有则找上一级的名称空间,直到内置空间都没有,则报错

2、函数名的本质

函数名的本质就是内存地址,计算机中变量本质上就是内存地址

函数()   函数的调用

函数的内存地址()    函数的调用

 

多个函数拥有多个独立的局部命名空间,不相互共享

def func():
    print("123")

func()    #func本质是内存地址
func2=func  #函数名也可以赋值

func2()  #执行func()函数

  • 函数名可以赋值
  • 函数名可以作为容器的元素
  • 函数名可以作为函数的参数
  • 函数名可以作为函数的返回值

 

3、作用域

  • 全局作用域   ——作用在全局——内置和全局名称空间中的名字都属于全局作用域
  • 局部作用域  ——作用在局部——函数 局部名空间中的名字属于局部作用域
  • global 变量名  在局部中声明变量为全局变量  尽量不要使用   不安全
a=1   #定义一个全局变量

def func():
  global a #声明为全局变量 声明过后就可以修改全局变量的值
a
+=1 func() print(a)

对于不可变数据类型,在局部可以查看和使用全局作用域的的变量,但是不能直接进行修改,如果要直接修改,需要在程序中局部变量前声明  global   a

locals()查看局部作用域中的名称  具体依据locals()的具体位置而定

globals()查看全局和内置命名空间中的名称

4、函数的嵌套和作用域链

1)函数的嵌套调用   只要函数中调用了其他函数就称为嵌套调用

def max(a,b): 
    """ 求两个值的最大值"""
    return a if a>b else b

def the_max(x,y,z):
    """函数的嵌套调用"""
    c=max(x,y)  #函数的嵌套调用
    return max(c,z)


print(the_max(1,2,3))

2)函数的嵌套定义

def  outer():

    def inner():
        print("inner")


outer()

内部函数可以使用外部函数的变量

nonlocal a 声明了一个上面第一层局部变量

后端语言(python/java/c++/c)                                                                          前端语言(html+js+css)

5、闭包

# 闭包
def outer():
"""外部函数"""
    a=1 
    def inner():
        """内部函数"""
        print(a)

闭包构成的条件

  • 必须为嵌套函数
  • 内部函数使用了外部函数的变量
def outer():
    a=2
    def inner():
        print(a) #内部函数使用外部函数的变量 a
        print(inner.__closure__)#打印函数是否为闭包

outer()
print(outer.__closure__)   #返回None表示不是闭包


闭包的用意场景

对于内部函数,传统的使用方式:

def outer():
    a=1

    def inner():
       """定义一个内部函数"""
        print(a)
    inner() #调用内部函数

outer()#调用外部函数

常见闭包形式

def outer():
    a=1

    def inner():
       """定义一个内部函数"""
        print(a)
    return  inner   #返回inner函数名

inn=outer()#调用外部函数
inn()# 在一个函数的外部使用内部的函数  这就是闭包

闭包的小应用

from urllib.request import urlopen

def get_url():
    url="http://www.xiaohua100.cn/index.html"
    ret=urlopen(url).read()
    print(ret)

get_url() #调用函数

使用闭包 无需频繁的创建和删除对应的使用变量

from urllib.request import urlopen

def get_url():
    url="http://www.xiaohua100.cn/index.html"

    def get():
        ret=urlopen(url).read() #获取网页的源码
        print(ret)

    return get

get_func=get_url() #调用函数

get_func()
get_func()
get_func()

二、作业

 

posted @ 2019-07-11 17:08  小小海鸥  阅读(80)  评论(0编辑  收藏  举报