从函数对象到名称空间与作用域

函数对象

函数(Function)作为程序语言中不可或缺的一部分。

在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的。

函数拥有对象的三个通用属性:值、id、类型

def pr_Hi():
    print('Hello World!')

print(id(foo))  # 21301264
print(type(foo))  # <class 'function'>
print(foo)  # <function pr_Hi at 0x01450810>

函数可以被引用

def pr_Hi():
    print('Hello World!')

pr_Hi2 = pr_Hi    #引用,赋值
print(pr_Hi2)  # <function pr_Hi at 0x03020810>
print(pr_Hi)  #<function pr_Hi at 0x03020810>
pr_Hi2()  # Hello World!

函数可以放入容器类数据类型

容器对象(list、dict、set等)中可以存放任何对象,函数也可以作存放到容器对象中

def pr_Hi():
    print('from pr_Hi')
dic={'func':pr_Hi}

pr_Hi()  # from pr_Hi

print(dic['func'])  # <function pr_Hi at 0x00BE0810>

dic['func']()  # from pr_Hi

函数还可以当做参数

def pr_Hi():
    print('from pr_Hi')  # from pr_Hi

def bar(func):  ##执行函数
    print(func)  # <function pr_Hi at 0x014E0810>
    func()  ##调用上面地址的函数

bar(pr_Hi)  ##第一步,先调用bar()函数

函数可以作为返回值

def pr_Hi():
    print('from pr_Hi')

def bar(func):
    return func     

f=bar(pr_Hi)

print(f)  # <function pr_Hi at 0x00CA0810>

f()  # from pr_Hi

函数还可以嵌套

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

abc = f1()  # f1()拿到函数的返回值,函数的返回值是f2, abc就相当于f2
abc()  # from f2

函数空间与作用域

一扯到函数的嵌套就不由自主的要开始扯函数空间与作用域了。

函数空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方

  • 内置名称空间:python自带的名字,在python解释器启动时产生,存放一些python内置的名字
  • 全局名称空间:在执行文件时,存放文件级别定义的名字
  • 局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的名称空间,用来存放该函数内定义的名字,该名字在函数调用时生效,调用结束后失效

名称空间的顺序

  • 加载顺序:内置名称空间 --> 全局名称空间 --> 局部名称空间
  • 查找顺序:局部名称空间 --> 全局名称空间 --> 内置名称空间

作用域: 产生作用的范围

  • 全局作用域:全局存活,全局有效
  • 局部作用域:局部存活,局部有效
x = 1

def f2():
    x = 2  # x=2只能在f2中使用
    print(x)
    
print(x)  # 1
f2()  # 2

如果实在要改变全局的变量或者是局部的变量

改全局名称
x = 1
def f1():
    global x
    x = 2
f1()
print(x)  # 2
改局部名称
x = 0
def f1():
    x = 1
    def f2():
        x = 2
        def f3():
            nonlocal x #改的是函数正上方的值
            x = 3
            print('f3',x)  # f3 3
        f3()
        print('f2',x)  # f2 3
    f2()
    print('f1',x)  # f1 1
print(x)  # 0
f1()
推荐使用引用类型
lt = [1,2,3]  # 作用域关系仅适用不可变数据类型,不适用于可变数据类型
def f1():
    lt.append(4)
print(lt)  # [1, 2, 3]
f1()
print(lt)  # [1, 2, 3, 4]

猜你喜欢

转载自www.cnblogs.com/Gredae/p/11329301.html
今日推荐