python入门_老男孩_函数进阶

关键字

  •   引子
  •   命名空间和作用域
  •   函数嵌套及作用域链
  •   函数名本质
  •   闭包

 

引子

  写函数,取三个数中的最大值,并打印 / 理解return的含义 / 进而命名空间及其规则

# 计算三个值中的最大值
def max(a, b):
    m = a if a > b else b
    return m

def t_max(x, y, z):
    c = max(x, y)
    return max(c, z)

print(t_max(1,2,3))
View Code
# 报错
def max(a, b):
    m = a if a > b else b
   
max(2, 3)
print(m)
View Code

  运行代码碰到函数时,python编译器只是把函数名放入内存中,并不关心其内在变量和逻辑关系;等到调用时,才用到其中的变量,并放入内存中;函数用完就清空其中变量,故打印错误。

 

命名空间

  存放名字和数值之间的对应关系

  分类

    全局命名空间

    局部命名空间  

    内置命名空间

  三种命名空间的加载顺序

    内置命名空间先于程序加载,全局命名空间从上到下加载,局部命名空间从上到下加载

 

作用域

  即作用范围

  全局作用域和局部作用域 

def func():
    a = 12
    b = 20
    print(locals())
    print(globals())

func()
View Code
# global关键字
a = 10
def func():
    global a
    a = 20

print(a)
func()
print(a)
View Code

 

函数的嵌套和作用域链

  嵌套

# in f1
# in f2
# in f3
def f1():
    def f2():
        def f3():
            print("in f3")
        print("in f2")
        f3()
    print("in f1")
    f2()
    
f1()
View Code

    注意:内部函数修改不可变外部参数会报错,只可以用,不可以改

def func():
    a = 1
    def func1():
        a += 1 # 不可修改
    func1()
    print(a)

func()
View Code

 

  作用域链

# a = 1
def f1():
    a = 1
    def f2():
        a = 2
    f2()
    print('a in f1 : ',a)

f1()
View Code

  nonlocal关键字

    外部必须有这个变量

    内部修改这个变量如果想在外部有这个变量的第一层函数中生效

def f1():
    a = 1
    def f2():
        nonlocal a
        a = 2
    f2()
    print('a in f1 : ',a)

f1()
View Code

 

函数名

  本质是内存地址 

  1. 可被引用

def func():
    print('in func')

f = func
print(f)
View Code

  2. 可被当作容器类型的元素

def f1():
    print('f1')


def f2():
    print('f2')


def f3():
    print('f3')

l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#调用
l[0]()
d['f2']()
View Code

  3. 可被当作函数的参数和返回值

  第一类对象 : 满足以上三种条件的对象

 

闭包

  内部函数中包含对外部作用域而非全局作用域名字的引用,该内部函数成为闭包函数

  通常拿到内部函数的名字,不必每次都建立一个有全局作用域的函数,效率高

def func():
    name = 'eva'
    def inner():
        print(name)
    return inner

f = func()
f()
View Code

  判断闭包函数的方法

#输出的__closure__有cell元素 :是闭包函数
def func():
    name = 'eva'
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f = func()
f()

#输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
    def inner():
        print(name)
    print(inner.__closure__)
    return inner

f2 = func2()
f2()
View Code

  闭包的嵌套

def wrapper():
    money = 1000
    def func():
        name = 'eva'
        def inner():
            print(name,money)
        return inner
    return func

f = wrapper()
i = f()
i()
View Code

  闭包函数获取网络应用

from urllib.request import urlopen

def index():
    url = "http://www.douban.com"
    def get():
        return urlopen(url).read()
    return get

douban = index()
content = douban()
print(content)
View Code

 

 

 

posted @ 2018-10-10 14:48  phappiness  阅读(242)  评论(0编辑  收藏  举报