函数的对象,嵌套,名称空间day10

今日学习总结:

一、函数对象:是指函数可以被当做数据来处理

ps:传参的时候没有特殊需求,一定不要加括号,加括号当场执行了

def index():
    print('hello')
index()
print(index)               # 输出的  就是函数index 的对象

结果:

hello
<function index at 0x0000000001FF2E18>

 

 

1.函数名可以被引用

def add(x,y):
    return x,y            #表示返回的 是一个元组
func = add                #表示函数名可以被引用
print(func(1,2))

2.函数名可以作为容器类型的元素

def func():
    print('hello word')
l1 = [1,'w',func,func()]       # func是函数名,func()是调用函数
f = l1[2]                            # 表示取出func 
print(f)                              #表示输出func 的对象


结果:
hello word
<function func at 0x0000000009EE27B8>

3.函数名可以当做参数传递

def foo(x, y, func):            #定义形参
    print(x, y)                
    func()                      # 这里的func()等于bar()
def bar():
    print('hello world')
foo(1, 2, bar)                  # 把函数名bar 传给func


结果:
1 2
hello worl

4.函数名可以当做返回值使用

def index():
    print('hello world')
def func(a):
    return a
s=func(index)      #把函数名index传给a 然后赋给s  这时 s就是index 了
s()


结果:
hello world

ps:重, 函数名可以当做返回值使用

x=111
def index():
    print(x)
    def wrapper():
        print(x)
    return wrapper    # 表示是返回值给了f
x=222
f=index()
f()

 

二、名称空间:存放名字与对象映射/绑定关系的地方。

1.内建名称空间: 伴随着python解释器的启动/关闭而产生/回收。所以内建名称空间是第一个被加载的名称空间,用来存放一些内置的名字,比如内建函数名。

                             python提前给你的定义完的名字,就是存在内置名称空间

这些 print int list 都是内建名称

print(print)
print(int)
print(list)

结果:

<built-in function print>
<class 'int'>
<class 'list'>

2.全局名称空间:伴随python文件的开始执行/执行完毕而产生/回收,是第二个被加载的名称空间,文件执行过程中产生的名字都会存放于全局名称空间中。

 存放文件级别的名字,就是全局名称空间。 if while for 内部定义的名字执行之后都存放于全局名称空间

x=1
print(x)
x=1
def index():
    print(x)
index()

3.局部名称空间:伴随函数的调用/结束而临时产生/回收。函数的形参、函数内定义的名字都会被存放于局部名称空间中。

 函数内部定义的所有名字都是存放与当前函数的内置名称空间

def index():
    x=1           
    print(x)
index
 def index():
     x=1
 index()
 print(x) # 不能这样写  因为x=1局部变量,print()中的x 没有被定义



修改为:
 x=2
 def index():
     x=1
 index()
 print(x) 


结果:2   因为x=1是局部变量  不能输出

 

三、作用域

1.全局作用域:位于全局名称空间、内建名称空间中的名字属于全局范围,该范围内的名字全局存活(在整个文件执行过程中)、全局有效(在任意位置都可以使用)

全局可以调用的名字就存在于全局作用域:内置名称空间+全局名称空间

2.局部作用域:位于局部名称空间中的名字属于局部范围。该范围内的名字临时存活(在函数调用时临时生成,函数调用结束后就释放)、局部有效(只能在函数内部使用)

局部可以调用的名字就存放于局部作用域:局部名称空间

3.global:声明全局变量,当想要改变不可变类型的变量时,可以用global

x = 1
def index():
     global x       #声明x=2是全局变量
     x = 2
index()
print(x)           # 2

例子:

b = 6
def test3(a):
    global b
    print(a)
    print(b)  # 当函数执行到这一步仍然会报错
              # UnboundLocalError: local variable 'b' referenced before assignment
    b = 9     # 比示例二多了一行赋值
    print(b)
test3(1)

结果:
1
6
9

 

4.nonlocal:在局部名称空间声明局部变量,在局部修改上层函数的变量。

x=111
def index():
x = 1
def func2():
x = 2
def func():
x = 3 # 这里x=3是灰色的,因为它是局部变量,没有被用到。
func()
print(x) # 这里x=3是灰色的,因为它是局部变量,没有被用到。所以打印的结果是 2
func2()
print(x)
index()
print(x)

结果:

2
1
111

使用nonlocal

x=111
def index():
    x = 1
    def func2():
        x = 2
        def func():
            nonlocal x      #在这里声明了x=3,则会改变上层的变量的值
            x = 3
        func()
        print(x)            #在这里声明了x=3,则会改变上层的变量的值,输出结果为:3
    func2()
    print(x)
index()
print(x)


结果:

3
1
111

 

ps :只有可变类型可以在局部修改外部变量的值

l1 = []            #l1是列表 是可变类型 ,如果换成不可变类型的元组就错了
def index(a):
    l1.append(a)   # 表示给列表l1添加值,改变列表
index(2)
print(l1)

四、名称空间的查找顺序:

1.在局部作用域查找名字时,因为起始位置是局部作用域,所以查找顺序为:局部名称空间--全局名称空间--内置名称空间

x=100            #全局作用域的名字
def foo():
    x=300        #局部作用域的名字
    print(x)     #在局部找x
foo()            #结果:300

2.在全局作用域查找名字时,因为起始位置是全局作用域,所以查找顺序为:全局名称空间--内置名称空间。

ps: 在全局作用域查找名字时,不会取局部作用域中的局部名称空间去找

x=100            #全局作用域的名字
def foo():
    x=300        #局部作用域的名字,
print(x)         #在全局找x
foo()            #结果:100

五、生命周期:

1.内置名称空间的生命周期:

在python解释器启动时生效,关闭解释器的时候就消失。

2.全局名称空间的生命周期:

当你启动这个py文件时生效,当前页面 代码执行结束之后失效

3.局部名称空间的生命周期:

当你调用当前函数时生效,函数体最后一行代码执行结束就失效

def index():
    x=1
    return x
print(index)
def foo():
    print(index)
foo()


结果:
<function index at 0x0000000009EE27B8>
<function index at 0x0000000009EE27B8>

六、特殊例子:

ps:函数内部使用的名字,在定义阶段已经定死了,与你的调用位置无关

x=1
def index(arg=x):        # 在这里把x=1的值给了arg  , arg=x是默认参数
    print(x)             # 在局部找
    print(arg)
x=2
index()
 
结果:
2
1

 

posted @ 2019-11-11 20:49  薛定谔的猫66  阅读(146)  评论(0)    收藏  举报