python函数进阶( 动态参数,*的魔性用法,名称空间,函数的嵌套,global,nonlocal)

用户传入到函数中的实参数量不定时,或者是为了以后拓展,
此时要用到动态参数*args,**kwargs(万能参数。)
*args接收的是所有的位置参数。
**kwargs接收的是所有的关键字参数
def func1(*args, **kwargs):
    print(args)
    print(kwargs)

# func1(1, 2, 3, 4)
# func1(x=4, y=5, z=6)
func1(1, 2, 3, x=4, y=5, z=6)

def func3(a):
    pass
func3(11)
位置参数,默认参数
def func2(a, b, sex=''):
    print(a)
    print(b)
    print(sex)
func2(1, 2, '')

# 位置参数,*args,默认参数
def func2(a, b, *args, sex=''):
    print(a)
    print(b)
    print(args)
    print(sex)
func2(1, 2, 5,6,7,8,9,sex='')
位置参数,*args,默认参数, **kwargs
def func2(a, b, *args, sex='',age=20, **kwargs):
    print(a)
    print(b)
    print(args)
    print(sex)
    print(age)
    print(kwargs)
func2(1, 2, 5, 6, 7, 8, 9, x=6, y=5, name='alex')
默认参数是可变类型数据时,无论使用多少次默认参数,都是一个。
def extendList(val,list=[]):    #list=[] 默认参数如果是可变数据类型时,无论使用多少次,都是一个。
    list.append(val)
    return list #return 将list变成了全局变量
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print('list1=%s'%list1) #第三步执行前是[10],第三步执行后是[10,'a']
print('list2=%s'%list2) #[123]   []不是默认参数,是新传进来的数据
print('list3=%s'%list3) #[10,'a']

def extendList(val,list=[]): #list=[] 默认参数如果是可变数据类型时,无论使用多少次,都是一个。 list.append(val) return list #return 将list变成了全局变量 list1 = extendList(10) print('list1=%s'%list1) #[10] list2 = extendList(123,[]) print('list2=%s'%list2) #[123] list3 = extendList('a') print('list3=%s'%list3) #[10,'a']
加法计算器
def sum (*args):
    ret=0
    for i in args:
        i=int(i)
        ret+=i
    return ret
print(sum(1,2,3))

def func1(*args):
    sum=0
    num=(input('请输入你的数字:')).strip()
    num=num.split('+')
    for i in num:
        i=int(i)
        sum+=i
    return sum

print(func1() )

def func3(*args,**kwargs):
    l = []
    for i in args:
        l.extend(i)
    args = tuple(l)
    print(args)
    print(kwargs)

l1 = [1, 2, 3]
l2 = [11, 21, 32]
func3(l1,l2) #l1,l2在内部转化

def func3(*args,**kwargs):#在函数定义时,*是集合
    # print(args)
    # return kwargs
    pass


l1 = [1, 2, 3]
l2 = [11, 21, 32]
dic={'name':'alex','age':'1000'}
print(func3(*l1,*l2,**dic))#函时数中没有return时,打印时会出现None
                             # l1,l2,**dic 在外部转化
                             # 在函数调用时,*是打散

# *的魔性用法
在函数定义时,*是集合
在函数的执行时,*的用意是打撒,关键字参数用**
l1 = [1, 2, 3]
l2 = [11, 21, 32]
s1 = 'fjskalgf'
s2 = 'fjskrrrf'
tu1 = (1, 2, 3)
tu2 = (11, 22, 33)
print(func3(*l1, *tu1, *tu2))
func3(1,2,3,1,2,3,11,22,33)
dic ={'name': 'alex'}
dic1 ={'age': 1000}
print(func3(*l1, **dic, **dic1) ) # func3(name='alex',age=1000)

def func(*args,**kwargs):
    print(args) #(1, 2, 3, 4, 5, 6)
    print(*args)    #1 2 3 4 5 6 又给打散了
    print(kwargs)   #{'name': 'alex', 'age': 28}
    # print(**kwargs)# 函数不能打印**kwargs

l1=[1,2,3,4,5,6]
dic={'name':'alex','age':28}
func(*l1,**dic) #  如果关键字参数用*dic ,则默认其为位置参数,将其传入形参结果为
                # (1, 2, 3, 4, 5, 6, 'age', 'name')
当程序运行时,代码从上至下一次读取,遇到变量与值,
他会在内存中开辟一个空间,存放变量与值的内存地址的对应关系。
这样存储变量与值得对应关系的空间叫做名称空间(命名空间)。
当解释器遇到函数时,他会将函数名存储在内存中,但是对于函数体莫不关心。
当函数执行时,他会通过函数名找到函数体,然后将函数体里面的变量等对应关系存放在一个
临时开辟的空间中,随着函数的结束,临时的空间关闭,这样的空间叫做临时名称空间
name = 'abc'
age = 1000

def func1():
    a = 2
    b = 3
func1()
内置名称空间:
len() print() input() list
list
name
print(666)
名称空间:
内置名称空间
全局名称空间
局部名称空间
加载顺序:内置名称空间 ---> 全局名称空间(程序运行时) ---->局部名称空间(函数执行时)
作用域:
全局作用域:内置名称空间 全局名称空间
局部作用域:局部名称空间
取值顺序(单项):局部名称空间(函数执行时) ---> 全局名称空间 ---> 内置名称空间
L local
E eclose
G global
B Built-in
sum = 666
name = 'aaa'
def func1():
    sum = 555
    print(sum)
func1()
sum = 666 # global
print(sum) #555 666

sum = 666 # global def func1(): sum = 555 # eclose print(sum) def inner(): pass sum = 111 # local print(sum) inner() func1()#555 111

函数的嵌套
print(111)   # 1
def func1():
    name = 'asd'
    print(name)  # 2
    def inner():
        a = 2
        print(a)  # 3
    inner()
func1() #111 asd 2

print(111)
def func1():
    name = 'asd'
    print(name)
    def inner():
        a = 2
        print(a)
    inner()
print(333)
func1()
print(444)#111 333 asd 2 444

print(111)
def func1():
    name = 'asd'
    print(name)
    def inner():
        a = 2
        print(a)
    inner()
print(333)
func1()
print(444)#111 333 asd 2 444

def func1():
    a = 666
    print(666)
def func2():
    name = 'aaa'
    print(name)
    func1()
print(333)
func2()
print(555)#333 aaa 666 555

def func1():
    print(666)  # 2

def func2():
    func1()
    print(333)  # 3
    def inner():
        print(222)  # 4
    inner()

print(111)  # 1
func2()
print(555)  # 5
global 
在全局名称空间里得到局部名称空间的变量。
1.return
2.global
1.在局部作用域中,声明一个全局变量
2.在局部作用域中,改变一个全局变量
3.对于可变的数据类型,函数中如果要对其操作,改变全局不用引用global.
nonlocal
不能改变一个全局变量
在局部作用域中,对父级作用域(或者更外层非全局作用域)的变量进行引用和修改,
引用的哪层,哪层及以下此变量全部发生改变。
global

def func1():
    name = 'asd'
    print(name)
    return name+'sb'
ret = func1()
print(ret)  #asd asdsb

def func1():
    global name#声明一个全局变量
    name = 'asd'
func1()
print(name)#asd

name = 'aaa'
def func1():
    global name #改变一个环境变量
    name = 'asd'
func1()
print(name)#asd


l1 = [1, 2, 3]
def func1():
    l1.append(666)#对于可变的数据类型,函数中如果要对其操作,改变全局不用引用global
func1()
print(l1)
nonlocal
name = "aaa"
def func1():
    nonlocal name# 不能对全局变量进行修改, 报错,找不到name变量
    print(name)
func1()

name = "aaa"
def func1():
    name = 'bbb'
    print(name)  # 1, bbb
    def inner():
        nonlocal name
        name = 'aaa'
        print(name)  # 2 aaa
    inner()
    print(name)  # 3,bbb aaa
func1() #bbb 老男孩 老男孩

b = 4def func1():
    global b
    b = 6
    def func2():
        nonlocal b#不能改变一个全局变量,报错,no binding for nonlocal 'b' found
        b = 666
        print(b)
    func2()
    print(b)
print(b)
func1()

局部名称空间(函数执行时)---> 全局名称空间(程序运行时)---> 内置名称空间
name='aaa'
def func1():
    global name
    name = 'bbb'

func1()
print(name)

def add_b():
    b = 42
    def do_global():
        b = 10  # 这一层
        print(b)  # 1,10
        def dd_nonlocal():
            nonlocal b
            b = b + 20
            print(b)  # 2,30
        dd_nonlocal()
        print(b)  # 3,30
    do_global()
    print(b)  #4,42
add_b()

tast

1、写函数,接收n个数字,求这些参数数字的和。(动态传参)
def func2(*args):
    sum=0
    ret=input('请输入内容:').strip()
    ret = ret.split('+')
    for i in ret:
        i=int(i)
        sum+=i
    return sum
print(func2())

def func2(*args):
    sum=0
    for i in args:
        sum+=i
    return sum
print(func2(1,2,3))
2、读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
a=10
b=20
def test5(a,b):#1 20 10
    print(a,b)#2   20 10 实参一一对应
c = test5(b,a)
print(c)#3  None  没有return,返回None
3、读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
a=10
b=20
def test5(a,b): #1 20 10
    a = 3
    b = 5
    print(a,b)#2  3 5
c = test5(b,a)  #test5(b,a)是函数的调用者
print(c)   #3 None  print(c)=print(test5) print(test5)没有发回值,所以是None
4.有函数定义如下:
def calc(a,b,c,d=1,e=2):
return (a+b)*(c-d)+e
请分别写出下列标号代码的输出结果,如果出错请写出Error。
print(calc(1,2,3,4,5))___2__ 
print(calc(1,2))_Error___
print(calc(e=4,c=5,a=2,b=3))__24_ print(calc(1,2,3))___8__
print(calc(1,2,3,e=4))___10_
print
(calc(1,2,3,d=5,4))_Error____
5,下面代码打印的结果分别是_________,________,________.
def extendList(val,list=[]):    #list=[] 默认参数如果是可变数据类型时,无论使用多少次,都是一个。
    list.append(val)
    return list #return 将list变成了全局变量
list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print('list1=%s'%list1) #第三步执行前是[10],第三步执行后是[10,'a']
print('list2=%s'%list2) #[123]   []不是默认参数,是新传进来的数据
print('list3=%s'%list3) #[10,'a']



def extendList(val,list=[]):    #list=[] 默认参数如果是可变数据类型时,无论使用多少次,都是一个。
    list.append(val)
    return list #return 将list变成了全局变量

list1 = extendList(10)
print('list1=%s'%list1) #[10]
list2 = extendList(123,[])
print('list2=%s'%list2) #[123]
list3 = extendList('a')
print('list3=%s'%list3) #[10,'a']

posted @ 2018-05-19 23:45  老虎死了还有狼  阅读(257)  评论(0编辑  收藏  举报