day10

默认参数的陷阱:

def qqxing(l = []):
    l.append(1)
    print(l)


qqxing()    #[1]
qqxing([])  #[1]
qqxing()    #[1,1]
qqxing()    #[1,1,1]

# 如果默认参数类型是可变数据类型,
# # 那么每次调用函数的时候,
# # 如果不传实参就共用这个数据类型的资源
View Code

 

函数的命名空间

 1 函数进阶
 2 a = 1
 3 def func():
 4     print(a)
 5 func()
 6 
 7 def func():
 8     a = 1
 9 func()
10 print(a)
11 
12 命名空间和作用域:
13 
14 命名空间 有三种
15 内置命名空间 ---- python解释器
16     就是python解释器一启动就可以使用的名字储存在内置命名空间中
17     内置的名字在启动解释器的时候被加载进内存
18 全局命名空间 ---- 我们写的代码但不是函数中的代码
19     是在程序从上到下被执行的过程中依次加载进内存的
20     放置了我们设置的所有变量名和函数名
21 局部命名空间 ---- 我们写的函数
22     就是函数内部定义的名字
23     当调用函数的时候 才会产生这个名称空间 随着函数执行的结束 这个命名空间就被回收
24 
25 在局部: 可以使用全局,内置命名空间中的名字
26 在全局: 可以使用内置命名空间中的名字,不能使用局部
27 在内置: 不能使用局部和全局的名字
28 
29 在正常情况下,直接使用内置的名字
30 当我们在全局定义了和内置名字空间中同名的名字,会使用全局的名字
31 当我自己有的时候 我就不找我的上级要
32 如果自己没有就找上级要 一次遍历所有上级直到内置空间 内置仍没有 就报错
33 多个函数应该拥有多个独立的局部名字空间 , 不互相共享
34 
35 def input():
36     print("in input now")
37 def func():
38     input()
39 
40 def func1():
41     a = 1
42 def func2():
43     a = 2
44 
45 func()  ==> 函数的内存地址()
46 函数名() 函数的调用
47 函数的内存地址() 函数的调用
48 
49 作用域两种
50     全局作用域 --- 作用在全局 --- 内置和全局名字空间的名字 都属于全局作用域 ---- globals()
51     局部作用域 --- 作用在局部 --- 函数(局部名字空间中的名字属于局部作用域) ---- locals()
52 
53 a = 1
54 def func():
55     global a
56     a += 1
57 
58 func()
59 print(a)
60 
61 对于不可变的数据类型 在局部是可查看全局作用域中的变量
62 但是不能直接修改
63 如果想要修改,需要在程序的一开始添加global声明
64 如果在一个局部(函数)内声明了一个global变量,那么这个变量在局部的所有操作对全局的变量有效
65 a = 1
66 b = 2
67 def func():
68     x = 'aaaa'
69     y = 'bbbb'
70     print(locals())
71 #func()
72 print(globals())
73 print(locals())
74 
75 globals() 永远打印全局的名字,尽量少的使用global,代码安全
76 locals() 打印当前局部的名字
View Code

 

函数的嵌套和作用域链

# def max(a,b):
#     return a if a>b else b
#
# def the_max(x,y,z): # 函数的嵌套调用
#     c = max(x,y)
#     return max(c,z)
#
# print(the_max(1,2,3))

# 函数的嵌套定义
# 内部函数可以使用外部函数的变量
# a = 1
# def outer():
#     a = 1
#     def inner():
#         b = 2
#         print(a)
#         print('inner')
#         def inner2():
#             nonlocal a #声明一个上层的局部变量,向上找的第一层
#             a += 1 #不可变数据类型的修改
#             print(a, b)
#             print('inner2')
#         inner2()
#     inner()
#     print('**a**', a)
# outer()
# print('全局的', a)

# nonlocal 只能用于局部变量,找上层中离当前函数最近一层的局部变量
# 声明了nonlocal的内部函数的变量修改会影响到 离当前函数最近一层的局部变量,这就叫作用域链
# 注意找不到全局那里去,对全局无效
# 对局部是最近的那层

#
# def func():
#     print(123)


#func() #函数名就是内存地址
# func2 = func #函数名可以赋值
# func2()
#
# l = [func,func2] #函数名可以作为容器类型的元素
# print(l)
#
# for i in l:
#     print(l)

def func():
    print(123)
def wahaha(f):
    f()
    return f #函数名可以作为函数的返回值
qqxing = wahaha(func) #函数名可以作为函数的参数
qqxing()

# 函数名是第一类对象
# 第一类对象(first-class object)
# 1,可以在运行期创建
# 2,可用作函数参数或返回值
# 3,可存入变量的实体
View Code

闭包:

在定义的函数内再使用其他函数的行为,就称为闭包

# 闭包: 嵌套函数,内部函数调用外部函数的变量
# def outer():
#     a = 1
#     def inner():
#         print(a)
#     print(inner.__closure__) # 打印结果出现cell就是闭包
# outer()
# print(outer.__closure__)

# def outer():
#     a = 1
#     def inner():
#         print(a)
#     return inner
# inn = outer()
# inn()

#import urllib # 模块
from urllib.request import urlopen
# ret = urlopen('http://fulibus.net/').read()
# print(ret)
# def get_url():
#     url = 'http://fulibus.net/'
#     ret = urlopen(url).read()
#     print(ret)
# get_url()
def get_url():
    url = 'http://fulibus.net/'
    def get():
        ret = urlopen(url).read()
        print(ret)
    return get

get_func = get_url()
get_func()
View Code

 

posted @ 2019-03-07 12:51  云川望雨  阅读(129)  评论(0编辑  收藏  举报