2019-07-10 函数的进阶(一)

 

1、函数对象python

    函数是第一类对象:函数名指向的值能够被当作参数传递函数

    1.函数名能够被传递spa

def func():
    print('from func')
f = func      #函数名能够被传递,这里用一个变量名赋值
func()    #from func
print(f)    #这里打印的是函数的内存地址
f()       #f()等价于  func()

    2.函数名能够被当作参数传递给其余函数code

def func():
    print('from func')

def index(args):
    print(args)      #等价于print(func)   打印函数func内存地址
    args()        #运行函数func()  执行内部代码
    print('from index')
index(func)    #函数名func当作参数名传递到index函数中



#结果
#<function func at 0x0000001A50EE0E18>
#from func
#from index

    3.函数名能够被当作函数的返回值对象

def index():
    print('index')
def func():
    print('func')
    return index
res = func()   #返回值是  index
print(res)   #打印函数名index的内存地址
res()    #调用运行index()函数


#结果
#func
#<function index at 0x0000001DB2490E18>
#index

    4.函数名能够被当作容器类型的参数blog

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



#结果
func
None
func      #为何结果有这个,由于在l调用了函数func(),因此打印一个func
[1, 2, <function func at 0x0000009769AF0E18>, None]  

2、函数调用    (在一个函数内部调用其余函数,能够将复杂的逻辑简单化)生命周期

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

def func():
    print('func')

index()


#调用index()以后,func()已经被定义了,能够被调用

3、名称空间内存

    名称空间是什么:就是存放变量名和变量值的内存地址的绑定关系的地方作用域

    名称空间的分类:io

      1.内置空间名称:python解释器提早给你定义好的名字(已经存放在内置名称空间了)

          就是一些内置函数:好比   len()/max()....

      2.全局名称空间:文件级别的代码

      3.局部名称空间:函数体内建立的名字都属于局部名称空间  

def func():
    username = 'jason'    #这个username是局部名称空间
    print(username)
func()

  总结:生命周期

    内置名称空间:只要python解释器已启动立马建立   关闭python解释器的时候内置名称空间自动销毁(针对于python解释器)

    全局名称空间:只要你运行py文件的时候会自动建立   py文件程序运行结束自动销毁 (针对于py文件)

    局部名称空间:函数被调用的时候建立  函数结束就销毁(针对于函数的调用开始结束)

 

4、名称空间的查找顺序

  注意:先要肯定好你当前在哪(在哪一个空间)

      查找顺序    

      1.若是你如今在全局:   全局  >>>内置   (先从全局找再到内置)

      2.若是你如今在局部:局部>>全局>>内置(先从局部找再到全局再到内置)

  例题:

  局部命名空间:先定位要打印的len属于什么空间,由于它是在函数里面的变量,因此它是局部名称空间,先找局部变量,正好函数里面有一个变量名赋值,因此这个len就从这取值

len = '我是全局名称空间的len'
def func():
    len = '我是局部名称空间的len'
    print(len)
func()

 

  全局和局部:咱们先来看红色的len,这个len在全局的位置,查找顺序先从全局开始,不会找到函数内部的局部。在全局里面已经有一个定义的len,因此用这个  '我是全局名称空间的len'。而后函数里面的len就和上面的同样了。

len = '我是全局名称空间的len'
def func():
    len = '我是局部名称空间的len'
    print(len)
print(len)  # 我如今站在的是全局的位置
func()

#结果
#我是全局名称空间的len
#我是局部名称空间的len

  局部:打印的x在局部位置,在自己函数没有,因此就往上一个找局部,找到有一个x。

def func():
    x = 1
    def index():
        print(x)  # 1
    return index

res = func()
x = 999
res()

  全局:若是把上一道题的局部x删掉,就要到全局里面找,找到x=999在函数调用以前已经定义了,最后结果就是999

def func():
    def index():
        print(x)  # 999
    return index

res = func()
x = 999
res()

  全局:x定位到局部,可是在inner里面找不到,outer里面也找不到,因此x是使用全局,后面的inner在哪里调用,x都是在全局找值

x=111
def outer():
    def inner():
        print('from inner',x)     #from inner 111
    return inner
f=outer()
def func():
    x=333
    f()
func()

  总结:函数在定义阶段就已经固定查找名字的顺序了,不会由于函数调用的位置改变而改变

5、做用域

  做用域就是做用范围,按照生效范围能够分为全局做用域和局部做用域

  全局做用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用,全局有效

  局部做用域:局部名称空间、只能在局部范围生效

  

  global和nonlocal

    global:在局部修改全局的不可变数据类型

    在下面这个若是不是用global,后面x和username打印的全局的值,就是1,jason。若是你使用了global,改变了全局变量的值,在下面设置x = 999,username = 'egon',打印的值也是这个。

    

    nonlocal:局部修改局部(函数嵌套)

    若是没有加nonlocal,x在局部找值,x=1。nonlocal 修改了前面x的值,在打印的时候变成2

          

    总结:global:局部修改全局,若是有多个,用逗号隔开

          nonlocal:局部修改局部,若是有多个,用逗号隔开

相关文章
相关标签/搜索