#*********************************** 作用域 ************************************************
#=================== 一、python中的作用域分4种情况(LEGB):===================
1、L:local,局部作用域,即函数中定义的变量。
2、E:enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的。
3、G:globa,全局变量,就是模块级别定义的变量;
4、B:built-in,系统固定模块里面的变量,比如int, bytearray等。
5、搜索变量的优先级顺序依次是:作用域局部>外层作用域>当前模块中的全局>python内置作用域,也就是LEGB。
x = int(2.9) # int built-in:调用系统模块产生的变量
g_count = 0 # global全局变量
def outer():
o_count = 1 # enclosing嵌套函数中变量,也就是outer函数中的局部变量
def inner():
i_count = 2 # local局部变量
print(o_count)#输出1
print(i_count) #报异常,找不到局部变量i_count
inner()
outer()
print(o_count) #报异常,找不到嵌套函数中的变量o_count
#=================== 二、作用域的产生 ===================
在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如if、try、for等)是不会引入新的作用域的。
if True:
x = 1 #条件语句下的变量是全局作用域的变量,条件语句并不能引入作用域
print(x) # 1
def fun():
x = 2 #函数下的变量是产生局部作用域的变量,仅在函数内可使用
print(x) # NameError: name 'x2' is not defined
#=================== 三、global和nonlocal关键字 ===================
当内部作用域修改外部作用域的变量时,要用global和nonlocal关键字声明。
global关键字:
当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下
count = 10
def outer():
global count #若没有声明,在下一条语句则是定义的局部变量count;声明后则是修改全局变量count
count = 100
print(count)
outer()
nonlocal关键字:
global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量时就需要nonlocal关键字了
def outer():
count = 10
def inner():
nonlocal count #count为局部作用域变量,若在嵌套作用域修改局部变量count,不能使用Global声明,必须使用nonlocal声明
count = 20
print(count)
inner()
print(count)
outer()
#*********************************** 函数 ************************************************
1、函数名可以作为参数输入
2、函数可以作为返回值
3、函数参数顺序对应
def user(name,age):#name和age按实参顺序对应形参
print('I am %s,I am %d'%(name,age))
user('alex',18)
4、函数参数标签对应
def user(name,age):
print('I am %s,I am %d'%(name,age))
user(age=16,name='alvin')#实参通过形参名称传值做对应,无序对应函数形参的顺序
5、函数形参如果有默认值,则函数调用时可不传该实参,使用默认值,且默认形参要放其他参数后面。
def print_info(name,age,sex='male'):
print('Name:%s'%name)
print('age:%s'%age)
print('Sex:%s'%sex)
return
print_info('alex',18)
print_info('铁锤',40,'female')
#一、无命名变长参数,即实参都不是键值对的形式
def add(*args):#*args表示不定长的参数,args接受的数据是元组类型
sum = 0
for i in args:
sum+=i
return sum
add(1,2)#可传多参数
add(1,2,3)#可传多参数
add(*[1,2,3])#实参列表前加*,可以将列表元素作为无命名变长参数传递给args,与add(1,2,3)等价
#二、有命名变长参数,即实参中有键值对的形式参数,*args,**kargs两参数位置不可变换位置
def logInfo(**kargs):#以字典形式接受变长实参
print(kargs)//获得命名的字典{'name'="Tom","sex":"male", "height":178}
for i in kargs:
print("%s:%s"%(i, kargs[i]))
logInfo(name="Tom",sex="male",height=178)
logInfo(**{name:"Tom",sex:"male",height:178})#实参字典前加**,可以将字典元素作为有命名变长参数进行传递。
#三、无命名变成参数与有命名变长参数,*args必须在左边,**kargs必须在右边,两参数位置不可变换;若再有默认参数在放最前面
def logInfo(*args, **kargs):
print(args)//获得无命名的元组("Tom", 18)
print(kargs)//获得命名的字典{"sex":"male", "height":178}
for i in kargs:
print("%s:%s"%(i, kargs[i]))
logInfo("Tom",18,sex="male",height=178)#无命名实参必须都放命名实参前面,不可交差。
函数中return返回多个对象时,函数返回值会以元组封装多个对象为结果进行返回
def func():
return 1,"Tom",[1,2,3]
print(func())//(1,"Tom",[1,2,3])
注意:
1、函数在执行过程中只要遇到return语句,就会停止执行并返回结果。
2、如果函数无return语句,那么函数的返回值为None。
3、函数return多个对象时,解释器会把这多个对象组装成一个元组整体返回。
#=================== 高阶函数 ===================
1、函数可以赋值给变量
def func():
print('hello')
foo = func
foo()#输出hello
2、函数可以作为参数进行传递
3、函数可以作为其他函数的返回值
#=================== 内置函数 ===================
1、filter函数:对序列中的元素依次执行fun1函数,将执行结果为True的item做成一个filter object的迭代器返回。可以看作是过滤函数。
str = ['a', 'b', 'c', 'd']
def fun1(s):
if s != 'a':
return s
ret = filter(fun1, str)# ret是一个迭代器对象
,占用空间小,使用时逐个取出
print(list(ret)) # ['b', 'c', 'd']
2、map函数:对序列中的元素依次执行fun1函数,将执行结果组成一个map object迭代器返回.
str = [1, 2,'a', 'b']
def fun2(s):
return s + "alvin"
ret = map(fun2, str)
print(ret) # map object的迭代器
print(list(ret))# ['aalvin', 'balvin', 'calvin', 'dalvin']
3、lambda表达式,因为lamdba在创建时不需要命名,所以也叫匿名函数
lambda格式:冒号(:)左侧表示函数接收的参数(a,b) ,冒号(:)右侧表示函数的返回值(a+b)。
add = lambda a,b : a + b
print add(2,3)#输出5