变量作用域
一个程序的所有变量并不是在哪个位置都可以访问的。访问权限取决于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。
如下为两种最基本的变量的作用域:
-
全局变量
-
局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。
举例:
num = 0 #全局变量
def sum(arg1,arg2):
#返回两个参数的和
num = arg1 + arg2 #num在这里是局部变量
print('局部变量:',num)
return num
sum(10,5)
print('全局变量:',num)
执行结果:
局部变量: 15
全局变量: 0
python中的作用域分4种情况
- L:local,局部作用域,即函数中定义的变量;
- E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
- G:globa,全局变量,就是模块级别定义的变量;
- B:built-in,系统固定模块里面的变量,比如int, bytearray等。 搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。
x = int(3.9) #int built-inf ,系统固定模块里面的变量;
g_count = 10 #globa,全局变量;
def outer():
e_count = 1 #enclosing,包含此函数的上级函数的局部作用域,但不是全局;
def inner():
l_count = 2 #local,局部作用域,函数中定义的变量;
print(o_count)
inner()
outer()
local和enclosing是相对的,enclosing变量相对上层来说也是local;
作用域产生
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的,如下代码,if并没有引入一个新的作用域,x仍处在当前作用域中,后面代码可以使用:
if 2>1:
x = 1
print(x) #结果为 1
def、class、lambda是可以引入新作用域的:
def test():
x = 2
print(x) #NameError: name 'x' is not defined
global关键字
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了,当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下,代码如下:
count = 20
def outer():
global count
print(count)
count = 200
print(count)
outer()
执行结果:
20
200
nonlocal关键字
global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量就需要nonlocal关键字了:
def outer():
num = 20
def inner():
nonlocal num
num = 100
print(num)
inner()
print(num)
outer()
执行结果:
100
100
总结:
(1)变量查找顺序:LEGB,作用域局部>外层作用域>当前模块中的全局>python内置作用域;
(2)只有模块、类、及函数才能引入新作用域;
(3)对于一个变量,内部作用域先声明就会覆盖外部变量,不声明直接使用,就会使用外部作用域的变量;
(4)内部作用域要修改外部作用域变量的值时,全局变量要使用global关键字,嵌套作用域变量要使用nonlocal关键字。nonlocal是python3新增的关键字,有了这个 关键字,就能完美的实现闭包了。
高阶函数
变量可以指向函数,函数的参数可以接收变量,那么函数可以接收另一个函数作为参数,这种函数称为高阶函数
1、函数名可以作为参数输入
2、函数名可以作为返回值
把函数作为实参:
def fun(f):
return f()
def hello():
return "hello world"
print(fun(hello))
hello world
把函数作为返回值:
def foo():
def hello():
return "hello world"
return hello
f = foo()
print(f())
hello world
系统内置高阶函数
1、map函数:接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并且把结果作为新的列表返回
def f(x):
return x**2
ty = map(f,(1,2,3,4))
li = list(ty)
print(ty)
print(li)
执行结果
<map object at 0x0141EA70>
[1, 4, 9, 16]
2、reduce函数:把一个函数作用到一个序列上,这个函数必须接收两个参数,reduce把结果和序列的下一个元素做累积计算
from functools import reduce
def add(x, y):
return x + y
print(reduce(add,range(1,5))) # 累加1+2+3+4
print(reduce(add, range(1, 10))) ## 4950 (注:1+2+...+9)
print(reduce(add, range(1, 10), 20)) ## 4970 (注:1+2+...+9+20)
执行结果:
10
45
65
3、filter函数:也接收一个函数和一个序列,和map函数不同的是,filter函数把传入的函数依次作用于每个元素,然后返回返回值是True的元素
例一:
str = ['a','b','c','d']
def fun(s):
if s != 'a':
return s
ret = filter(fun,str)
print(list(ret))
['b', 'c', 'd']
例二:
def str(k):
if k % 2 == 0:
return True
else:
return False
ret = filter(str,range(1,11))
print(list(ret))
打印结果:
[2, 4, 6, 8, 10]
参考:https://www.cnblogs.com/yuanchenqi/articles/5828233.html