作用域与函数

#*********************************** 作用域 ************************************************
#=================== 一、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
 

  

posted @ 2022-11-17 21:59  大碗麻辣烫  阅读(8)  评论(0)    收藏  举报