1.闭包
- 函数中定义一个函数,函数内部定义函数称为内部函数,内部函数只能在函数内使用,不会污染外部空间,定义内部函数得函数称外部函数.
- 外部函数定义内部函数,内部函数引用外部函数变狼,且外部函数返回值内函数引用,这样内部函数和执行所徐环境比变量构成一个闭包
- 函数结束,函数内东西释放掉,局部变量会消失,闭包是一种个数情况,函数结束时发现自己局部变量会在函数中用到,把局部变量绑定给了内部函数,然后自己结束。
def outer(): # 外部函数
print("外部函数")
a = 10
def inner(): # 内部函数
# a += 90 # 不可以修改外部变量
print(a) # 1 在内部函数里使用外部函数里的变量
print("内部函数")
return 30
return inner # 2.外部函数返回内部函数的函数名
pf = outer() # pf就是inner
res = pf()
print(res)
- 闭包中无法直接修改外部变量X得值,在Python中通过nonlocal关键字声明一下x,表示这个变量不是局部变量,需要向上一层变量空间找这个变量。
# 使用nonlocal关键字修改外部变量x得值
def outter(a): # 外部函数
x = a
def inner(y):
nonlocal x
x += 10
return x + y
return inner
pf = outter(10)
print(pf(10)) # 输出30
2.偏函数
- 函数有大量参数,调用时不方便,可以使用偏含函数技术,将一些参数固定(给默认值),达到简化函数调用得目的。
import functools
def test(a,b,c,d):
print(a,b,c,d)
# 从前面固定参数,使用位置参数,1=>a,2>b
test1 = functools.partial(test,1,2)
test1(3,4) # 3=>c 4>d
# 从后后面固定参数,使用关键字参数
test2 = functools.partial(test,c=2,d=1)
test2(4,3) # 4=>a,3=>b
# 如果固定参数不连续,使用关键字参数固定
test3 = functools.partial(test,b=6,d=8)
test3(a=5,c=7) # a=>5,c=>7
3.变量得作用域
- 程序变量不是任意位置可以访问,在哪访问取决于变量得作用域(变量作用域:指变量在那段代码中可以使用,可以使用那段代码就是变量得作用域)
- Python中,函数/类/模块引入作用域,if/elif/else,while/for,try/except不会引入新的作用域
# if语句不引入新作用域,msg在外面可以使用
if 1:
msg = "message"
print(msg)
3.1 变量作用域的分类
- L:Local,局部作用域
- E:Enclosing,闭包作用域【闭包的外不函数中定义的变量】
- G:Global,全局作用域 在所有函数外定义的变量
- B:Built-in,内建作用域【内置作用域】
# 局部作用域
# 局部变量只能在函数体内使用,外部无法引用
# 局部变量的作用域从定义开始到函数体结束
def demo():
num = 20 # 局部变量
print(num)
demo()
# print(num) 错误提示:NameError: name 'num' is not defined
# 闭包作用域
def outter():
x = 10 # 函数作用域,从定义开始到本函数结束
def inner():
y = x # 在闭包中可以引用
print(y)
return inner
pf = outter()
pf() # 执行闭包
print(pf.__closure__) # 返回:cell 闭包 (<cell at 0x000001C417532F70: int object at 0x00007FFEADB7C7C0>,)
# 全局作用域
x = 100 # 全局作用域 从定义开始到本文结束
def dem1():
print(x) # 不输出
print(x) # 输出100
# 内建作用域,指系统内建的函数常量,系统载入加载,所有模块可以直接应用
# 系统函数
print(max(1,2,3)) # max函数时内建作用域,哪里都可以引用 输出3
def dem2():
x = 30
y = 50
return max(x,y)
print(dem2()) # 输出50
3.2 变量作用域查找规则
- 以L–>E–>--G–>B规则查找,即:局部找不到,会去局部外的局部朝朝(闭包),找不到就会去全局找,最后到内建作用域中找。
3.3 全局变量和局部变量
- 定义在函数体内部的变量又有一个局部变量作用域,称为局部变量
- 定义在函数体外面的变量拥有一个全局作用域,被称为全局变量
- 局部变量和全局变量相同名,局部优先
total = 0 # 全局变量
def sum(arg1,arg2):
total = arg1 + arg2 # 局部变量
print("函数内部:",total)
return total
sum(10,20) # 输出30
print("函数外部:",total) # 输出0
num = 1
def fun1():
print(num) #UnboundLocalError: local variable 'num' referenced before assignment / Python的局部变量在没有被赋值之前被引用了
num = 123
print(num)
fun1()
3.4 global和nonlocal
# Python中,内部作用域向修改全局变量的时候,使用global关键字进行声明
num = 1
def fun1():
global num # 告诉编译器,次数num时全局变量
print(num) # 输出:1
num = 123
print(num) # 输出:123
fun1()
a = 10
def test():
global a
a += 1
print(a) # 输出:11
test()
# 如果要修改函数作用域中的变量,使用nonlocal
# 明确的时,nonlocal关键字在闭包里面
# nonlocal关键字:声明该变量不只是在outer函数中有效,在inner函数内部也有效
x = 0 # 全局变量
def outer():
x = 1 # 闭包作用域
def inner():
nonlocal x
x = 2 # 局部作用域
print("inner:",x) # 2
inner()
print("outer:",x) # 1----->2
outer()
print("全局:",x) # 0
4.冒泡排序
- 冒泡排序(Bubble Sort)简单直观排序算法,重复访过排序的数列,一次比较两个元素,如果顺序错误就把他们交换过来。
Python冒泡排序:https://www.runoob.com/python3/python-bubble-sort.htm
# 方法一:
def bubbleSort(arr):
n = len(arr)
# 遍历所有的数组元素
for i in range(n):
# Last i elements are already in place
for j in range(0,n-i-1):
if arr[j] > arr[j + 1]:
arr[j],arr[j + 1] = arr[j + 1],arr[j]
arr = [64,34,25,12,22,11,90]
bubbleSort(arr)
print("排列后的数组:")
for i in range(len(arr)):
print("%d" %arr[i])
# 方法二:可选择升序降序排序
# 可选升降序的冒泡排序,order > 0升序,order < 0 降序
def bubbleSort(arr,order):
max = len(arr)
for i in range(0, max):
j = 1
while(j<max-i):
if((arr[j-1]>arr[j]) and (int(order)>0)) or ((arr[j-1]<arr[j]) and (int(order)<0)):
arr[j-1], arr[j] = arr[j], arr[j - 1]
j += 1
i += 1
return arr
A = [64, 25, 12, 22, 11]
print(bubbleSort(A, -1))
print(bubbleSort(A, 1))