函数 对象,嵌套,名称空间作用域

一.函数的对象

 函数是第一类对象:函数名对应的值(函数体代码)可以被当作参数传递
1.函数名可以被传递(类似变量)

name = 'waller'
ures_name = name  # 变量名的传递
print(ures_name)  # >>> waller

def func():
    print('name is waller')
print(func)  # 打印的是函数体代码的内存地址  <function func at 0x000002EF3AA02EA0>
print(id(func))  # 打印的是函数名在内存里的地址  3226504015520
f = func  # func对应的函数内存地址也赋值给f
print(f)  # 打印的是函数体代码的内存地址  <function func at 0x000002EF3AA02EA0>

f() # 调用函数,等价与func()
 


2.函数名可以被当作参数传递给其他函数
def func():
    print('from func')

def info(regs):
    print(regs)  # <function func at 0x000001A378C62EA0>
    regs()  # from func
    print('from info')  # from info
info(func)


3.函数的名可以被当作函数的值被返回
def func():
    print('from func')
def info():
    print('from info')
    return func
info()  # >>> from info 是打印函数运行的结果,并且由返回值可接收
res = info()  # >>> from info # 函数的返回值赋值给变量 res
print(res)  # >>> <function func at 0x000002C27E772EA0> # 等价于 print(func)
res()  # >>> from func # 等价于 func()

4.函数名可以当作容器类型数据里的元素
def func():
    print('from func')
print(func())  # 优先运行func()函数,运行结果是from func,有返回值None被print打印了出来9
l = [1,2,func,func()]  # 容器类型数据是把func()函数的 返回值 放入其中,而不是函数运行结果
print(l)  # >>> [1, 2, <function func at 0x0000024143502EA0>, None]

二.函数嵌套

在函数内部调用其他函数,可以使复杂的逻辑简单化
def my_max(x,y):  # 定义可以比较两个数大小的函数
    if x > y:
        return x
    return y
# print(my_max(2,5))  # >>> 打印出函数运行的返回值

def my_max1(a,b,c,d):
    res1 = my_max(a,b)  # 接收两个数比较后的返回值
    res2 = my_max(res1,c)
    res3 = my_max(res2,d)
    return res3  # 接收最终的返回值
print(my_max1(2,4,6,8))  # >>> 8 # 打印出四个数比较大小的返回值

三.名称空间

存放变量名的地方,存放的使变量名与变量地址绑定关系的地方
要想访问一个值,必须要到名称空间找到变量名才能访问到变量值

名称空间分类:

1.内置名称空间:
python解释器提前定义好的名字存在了内置名称空间(len,max,print,range...)
2.全局名称空间:
文件级别的代码,一般是程序员按照变量名命名规范所起的变量名
3.局部名称空间:
函数体内创建的变量名都属于局部名称空间

生命周期:
1.内置名称空间:python解释器启动创建,python解释器关闭自动销毁
2.全局名称空间:右键运行py文件创建,py文件运行完毕自动销毁
3.局部名称空间:函数调用时创建,函数运行结束立即销毁(动态创建,动态销毁)

查找顺序:
先确定当前位置(*****):
如当前位置在全局:全局 >>> 内置
如当前位置在局部;局部 >>> 全局 >>> 内置

函数在定义阶段名字的查找顺序就已经确定了,不会应为函数的调用位置变化而改变(*****)

name = '全局名称空间'
def func():
    name = '局部名称空间'
    print(name)
func()  # >>> 局部名称空间
print(name)  # >>> 全局名称空间


name = '全局名称空间'
def func():
    print(name)
func()  # >>> 全局名称空间

# 变量名先定义再调用
def index():
    print(x)
    x = 666
index()  # 报错
def index():
    x = 10
    print(x)

def index2():
    print(x)
index()  # >>> x
index2()  # 报错 并行的函数无法交叉查找变量名
x=111
def outer():
    def inner():
        print('from inner',x)  # 函数在定义阶段名字的查找顺序就已经确定了
    return inner
f=outer()
def func():
    x=333
    f()  # 不会应为函数的调用位置变化而改变
func()  # >>> from inner 111

作用域

全局作用域:全局生效
局部作用域:局部生效

global:局部修改全局,如修改多个,用逗号隔开
nonlocal:局部修改局部,如修改多个,用逗号隔开
# 局部修改全局
name = 'waller'
age = 20
def func():
    global age,name  # 声明
    age = 22
    name = 'wong'
    print(name,age)
func()  # wong 22
print(name)  # wong
print(age)  # 22

# 局部修改局部
def func():
    x = 1
    def info():
        nonlocal x
        x = 2
    info()
    print(x)
func()  # >>> 2
 
 
 

原文地址:https://www.cnblogs.com/waller/p/11165799.html