函数(二)

函数对象:

函数是第一类对象:函数名指向的值可以被当做参数的传递

 

1:函数名可以被传递

def func():
    print('123')
print(func)
 
f = func # f现在就等同于func,因为它也指向了func的内存地址
f()    

>>>
'123'

 

 

2:函数名还可以被当作参数传递给其他函数

def func():
    print('func1')
def index(args):
    print(args)
    args()
    print('func2')
 
index(func)

>>>
<function func at 0x000002B51C6C1E18>
func1
func2

 

 

3 函数名可以被当作函数的返回值

def index():
    print('index')
def func():
    print('func')
    return index
res = func()
print(res)
res()

>>>
func
<function index at 0x0000022F2F101E18>
index

 

 

 

4:函数名可以被当作容器类型的参数

def func():
    print('func123')
l = [1,2,func,func()]
print(l)

>>>
func123
[1, 2, <function a at 0x000001B595271E18>, None]

 

 

函数的嵌套调用

# 在函数内部调用其他函数

# 可以把复杂的逻辑简单化

 

def index():
    # func()
    print('index')
        
def func():
    index()
    print('func')
func()

>>>
index
func

# 这个代码是没有问题的,因为走到func()的时候,两个函数都已经被创建好了

 

 

 

 

 

函数的嵌套定义

# 在外部不能直接调用函数内部的函数

# 把复杂的东西放在函数中,给用户暴露一个简单接口

 

def outer():
    x = 1
    print('outer')
    def inner():
        print('inner')
    return inner

res = outer()
res()
>>>
outer
inner

 

 

 

def outer():
    x = 1
    print('outer')

    def inner():
        print('123')

    # print(inner)  # 能够得到inner的内存地址
    return inner


res = outer()
res()
>>>
outer
123

 

def func(a):

    def a1():
        print('a1111')

    def b2():
        print('b222222')

     d1 = {
        '1': a1,
        '2': b2
    }

return d1[a]
func('1')()

>>>
a1111

 

 

名称空间:

名称空间是什么:

就是放名字的地方,

详细解释:

存放的是变量名与变量值的内存地址的绑定关系的地方

要想访问一个变量的值 必须先去名称空间中拿到对应的名字 才能访问变量的值

 

name = 'cly'

 

名称空间的分类

1:内置名称空间:

python解释器提前就定义好了的名字(已经存放在内置名称空间中了)

len

max

min

print

2:全局名称空间:

文件级别的代码:

一个变量可以在文件中任何使用

 

if for while 无论嵌套多少层,它们内部创建的名字都是全局名称空间

 

3:局部名称空间:

  函数体内创建的名字都是局部名称空间(出了函数,外面就无法访问)

 

存活周期:

内置名称空间:

只要python解释器启动了,就会立马创建,关闭python解释器的时候,内置名称空间就被销毁了

 

全局名称空间:

只要运行了.py文件,就会自动创建,.py文件运行结束,就会自动销毁

函数名也是全局名称空间。

 

局部名称空间:

函数被调用的时候就会自动创建,函数结束名称空间就会被销毁(动态创建,动态销毁)

 

 

名称空间查找顺序

名字查找:

1:确定你在当前在哪

1:全局

全局>>>内置

2:局部

局部>>>全局>>>内置

 

 

 

 

函数在定义阶段查找名字就已经固定了,不会因为函数的调用位置变化了而发发生变化

(如果是在内置中找不到,就会往上一层,如果上一层还没有,就上一层又上一层寻找)

 

 

 

它因为当前空间没有,他就会往上一层空间寻找,如果有就不会往上找了,但是因为还没有创建x = 66666666(有x = 66666666),所以会报错

把 x = 66666666删掉就不会报错了,因为删除之后它的上一层就没有了,就会寻找上一层的上一层

 

 

 

作用域:

 

全局作用域,局部作用域

 

全局作用域:

内置名称空间+全局名称空间

局部作用域:

局部有效

 

global

nonlocal

 

 

x = 1
def func():
x = 2
func()
print(x)

>>>
1

 

 

global:

# 局部修改全局,如果修改多个,逗号隔开

x = 1

name = 'cly'

# global 在局部修改一个在全局的不可变类型

def func():

    global x,name # 修改全局变量,而不是创建局部空间

    ame = 'ccc'

    x = 2

func()
print(x)
print(name)

>>>
2
ccc

 

 

 

nonlocal:

 

# 从局部修改局部的变量,修改多个,逗号隔开
def func():
    x = 1
    def index():
        nonlocal x
        x = 2
    index()
    print(x)
func()

>>>
2

 

 

 

 

 

 

 

 

 

posted @ 2019-07-10 21:52  Pscly  阅读(197)  评论(0编辑  收藏  举报