函数进阶

一、命名空间和作用域

  1.命名空间

    分为内置命名空间(最上层),全局命名空间(低一层)、局部命名空间(底层)

# 内置命名空间:不能使用全局、局部的变量(不依赖)
#     python解释器启动就可用,例如print,input,list,tuple,when等
#     内置的名字在启动解释器的时候被加载进内存。
# 全局命名空间:可以使用内置,不能使用全局
#     程序执行过程中依次加载进内存。防止设置的所有函数名和变量名
# 局部命名空间:可以使用全局、内置.并且多个局部命名空间不能串用
#     函数内部定义的变量名,当调用函数时才会产生名称空间,函数调用结束,命名空间就回收
# 如果在全局名字空间定义的变量名是关键字(如input或max)和内置名字空间中同名的名字时
# 那么调用的就是自己定义的函数
#局部的命名空间时,假如使用一个已经自定义,但是同时也是关键字的名字,那么会向上级,就是全局变量找,可以找到。
#如果在内置命名空间都没有,就会报错
#函数名去掉括号,就指向函数的内存地址,加括号就是调用执行。也就是内存地址+()=执行

  2.作用域

#作用域
#全局作用域:作用在全局-内置和全局名字空间中的名字都属于全局作用域
#局部作用域:作用在局部-函数,局部名字空间中的名字
#对于不可变数据类型,在局部只能查看不能直接修改,想修改需要在程序一开始添加global声明
#局部作用域中的使用locals函数可以查看当前函数内所有的名字
#globals永远打印全局的名字,locals看当前在全局还是局部打印当前的所有名字
# #global不是特别安全,可以通过接收参数和传参,更安全a=func(a),就可以修改了

二、函数进阶

  1.函数嵌套

# 函数的嵌套定义
def outer():
    def inner():
        print("c")

outer()  #什么都不会发生,并没有调用inner(),inner就会消失
def outer():
    a = 'n'
    def inner():
        print("c")
        print(a)    #会打印,因为上级有a
    inner()

outer()  #打印
#c
#n

  2.闭包

#函数的闭包
#闭包:嵌套函数,内部函数调用外部函数的变量
def outer():
    a=1
    def inner():
        print(a)        #只要用上外部函数的变量,就是闭包
    print(inner.__closure__)

outer()
print(outer.__closure__)

def outer():
    a=1
    def inner():
        print(a)
    return inner()
inx=outer()   #函数作为返回值
inx           #在函数外部使用函数内部

  闭包的应用:节省资源

  闭包的示例:爬取网络页面

#闭包的应用(爬虫示例)
#import urllib    #模块
from urllib.request import urlopen
ret = urlopen('http://www.baidu.com').read()#要联网
print(ret)


#检查console,查看网页源代码
def get_url():
    url='http://www.baidu.com'   #flag1
    def get():
        ret=urlopen(url).read()
        print(ret)
    return get
get_func=get_url()   #节省资源,就不用生成外部的flag1的资源
# 相当于把源码获得,类似wget,只是将网页down下来
原文地址:https://www.cnblogs.com/lowislucifer/p/10969796.html