zoukankan      html  css  js  c++  java
  • 巨蟒python全栈开发-第10天 函数进阶

    一.今日主要内容总览(重点)
    1.动态传参(重点)  *,**
    *:
    形参:聚合
    位置参数*=>元组
    关键字**=>字典
    实参:打散
    列表,字符串,元组=>*
    字典=>**

    形参顺序:
    位置,*args,默认值,**kwargs

    无敌传参:
    def func(*args,**kwargs): #arguments参数, keyword-arguments关键字参数
    pass

    2.作用域和名称空间
    名称空间:用来存放名字(变量,函数名,类名,引入的模块名字)的

    1.全局名称空间:我们在py文件中自己写的变量,函数...
    2.内置名称空间:我们python解释器提供好的一些内置函数(print,input...)
    3.局部名称空间:在我们执行函数的时候,会产生一个局部名称空间.放的是:函数内部的内容(变量,函数,类...)

    名称空间可能会有无数个,局部名称空间,相对是独立的,一般互不干扰

    作用域:
    1.全局作用域:内置+全局
    2.局部作用域:局部

    globals() 查看全局作用域
    locals() 查看当前作用域

    #函数调用完毕,函数开辟的空间自动关闭
    #全局不能找局部的变量
    #但是局部可以找全局

    3.函数的嵌套
    在函数中声明函数
    在内部函数中使用变量的时候,查找顺序:先找自己=>上一层=>上一层..全局=>内置

    4.nonlocal和global关键字(重点)
    golbal:在局部引入全局变量
    nonlocal:在局部...内层函数引入外层离他最近的那个变量

    下周预习:
    第一类对象(函数名,他就是个变量名),闭包,迭代器
    生成器,各种推导式
    内置函数1,内置函数2
    装饰器(头疼),装饰器进阶

    模块 //一个周
    面向对象 //一个周

    DAY10-函数进阶

    二.今日内容大纲
    1.动态传参
    2.名称空间&作用域
    3.函数的互相调用和函数的嵌套
    4.nonlocal&global


    三.内容详解
    1.动态传参
    (1)
    分别传递给形参
    def chi(zhushi,cai,fushi,tang,tiandian):
        print(zhushi,cai,fushi,tang,tiandian)
    chi('大碗大米饭','火爆大头菜','把子肉','西红柿鸡蛋汤','烤地瓜')
    #吃不够灵活//
    chi('小碗大米饭','火爆大头菜','','','')#参数不够报错或者必须这样写
    
    '''
    结果:
    大碗大米饭 火爆大头菜 把子肉 西红柿鸡蛋汤 烤地瓜
    小碗大米饭 火爆大头菜
    '''
    (2)
    形参的顺序(重点)
    位置参数 *args 默认值参数 **kwargs
    以后写参数.可以随意的进行搭配,但是,顺序不能串

    *在形参位置,*表示不定参数-接收的是位置参数
    在接收到的位置参数的动态传参:都是元组
    def chi(*food):     #在形参这里把传递过来的实参进行了聚合,聚合成了元组
        print(food)
    chi('小米粥')
    chi('小米粥','咸鸭蛋')
    chi('爆米花','咸鸭蛋','辣白菜')
    chi('小米粥','爆米花','咸鸭蛋','蒜茄子')
    
    '''
    结果:
    ('小米粥',)
    ('小米粥', '咸鸭蛋')
    ('爆米花', '咸鸭蛋', '辣白菜')
    ('小米粥', '爆米花', '咸鸭蛋', '蒜茄子')
    (3)
    位置参数放在前面,动态位置参数放在后边
    解释后边的*args会聚合 4,5,6,7形成一个元组
    def func(a,b,c,*args):
        print(a,b,c,args)
    func(1,2,3,4,5,6,7)
    '''
    结果:
    1 2 3 (4, 5, 6, 7)
    '''
    (4)
    动态位置参数放在前面,默认参数放在后边
    def func(*args,a,b,c):
        print(a,b,c,args)
    func(1,2,3,4,5,6,7,a=8,b=9,c=10)
    '''
    结果:#注意位置
    8 9 10 (1, 2, 3, 4, 5, 6, 7)
    (5)
    key word arguments #关键字参数
    **在形参中表示动态传参-关键字传递参数
    关键字动态传参接收到的是字典
    (5-1)
    def func(**kwargs): #也是聚合 ** 聚合成字典
    print(kwargs)
    func(1,2,3,4,5)

    '''
    报错结果分析:(位置参数,报错)
    表面上不报错,但是运行起来会报错
    func() takes 0 positional arguments but 5 were given
    func()采用0个位置参数,但给出了5个
    (5-2)
    def func(**kwargs):     #也是聚合   **  聚合成字典
        print(kwargs)
    func(a=1,b=2,c=3,haha='呵呵',good='not bad')
    #这里必须是关键字传参,不能是位置传参
    '''
    # 结果:
    {'a': 1, 'b': 2, 'c': 3, 'haha': '呵呵', 'good': 'not bad'}
    '''
    (6)
    #默认值不生效,下面两种写法都可以
    正确写法
    def func(gender='',**kwargs):
        print(gender,kwargs)
    func(gender='',a=5,b=6,c=7)
    func('',a=5,b=6,c=7)
    
    错误写法
    def func(**kwargs,gender=''):
        print(gender,kwargs)
    func(gender='',a=5,b=6,c=7)
    func('',a=5,b=6,c=7)
    重点:
    形式参数的顺序:
    位置参数 *args 默认值 **kwargs

    以后写参数,可以随意的进行搭配,但是必须按照上边的顺序
    (7)
    无敌传参案例
    实参,不进行传递参数也是可以的
    def func(*args,**kwargs):  #参数没有限制,随便传递
        print(args)
        print(kwargs)
    func(1,2,3,4,5,a=3,b=5)
    #结果:
    (1, 2, 3, 4, 5)
    {'a': 3, 'b': 5}
    (8)
    for循环只能纵向打散,不能横向打散
    这里是形参 *代表聚合

    (8-1)
    def chi(*food):
        print(food)
    lst=['胡萝卜','大白菜','大萝卜','','果冻']
    #这里是实参 代表打散
    chi(*lst)
    '''
    结果:('胡萝卜', '大白菜', '大萝卜', '草', '果冻')
    '''
    (8-2)
    def chi(*food):
        print(food)
    lst=['胡萝卜','大白菜','大萝卜','','果冻']
    for el in lst:
        chi(el)
    
    '''
    # 结果:
    # ('胡萝卜',)
    # ('大白菜',)
    # ('大萝卜',)
    # ('草',)
    # ('果冻',)
    '''
    (8-3)
    def chi(*food):
        print(food)
    lst=['胡萝卜','大白菜','大萝卜','','果冻']
    chi(lst[0],lst[1],lst[2],lst[3],lst[4],)
    '''
    结果:('胡萝卜', '大白菜', '大萝卜', '草', '果冻')
    '''
    (8-4)
    字符串迭代元素换成元组
    def chi(*food):
        print(food)
    chi(*'你今天吃了什么')    #打散,把列表,元组,字符串打散成位置参数进行传递
    s='冬瓜'
    chi(s)
    chi(*s)
    chi('红鲤鱼','绿鲤鱼','')

    结果:

    结果:#字符串迭代元素换成元组
    ('', '', '', '', '', '', '')
    ('冬瓜',)                 #直接传是这样
    ('', '')              #聚合是这样
    ('红鲤鱼', '绿鲤鱼', '')
    (8-5)
    和8-4的最后一例一样
    和8-4的最后一例一样
    def chi(*food):
        print(food)
    chi('大白菜','大冬瓜')
    
    '''
    结果:('大白菜', '大冬瓜')
    '''
    (9)
    (9-1)#三种调用写法
    def chi(**food):    #聚合,聚合成字典
        print(food)
    dic={'主食':'面条','副食':'土豆泥','':'疙瘩汤'}
    chi(**dic)
    chi(**dic, 甜点="冰激凌") # 打散. 打散成关键字
    chi(主食="面条", 副食="土豆泥", 汤="疙瘩汤", 甜点="冰激凌")
    chi(主食='面条',副食='土豆泥',汤='疙瘩汤')
    '''
    结果:
    {'主食': '面条', '副食': '土豆泥', '汤': '疙瘩汤'}
    {'主食': '面条', '副食': '土豆泥', '汤': '疙瘩汤', '甜点': '冰激凌'}
    {'主食': '面条', '副食': '土豆泥', '汤': '疙瘩汤', '甜点': '冰激凌'}
    {'主食': '面条', '副食': '土豆泥', '汤': '疙瘩汤'}
    '''

    总结:

    动态传参*总结:
    形参:
    *->元组,
    **->字典 表示聚合
    实参:
    *->列表,字符串,元组
    **->字典 表示打散

    2.名称空间&作用域
    (1)引入
    a=10
    lst=[1,2,3,4]
    #内置函数print
    print('你好啊,我叫盖伦')
    (2)
    def chi():
        a = 10
        b = 20
    # 如果不调用chi() chi中的a和b都不会创建
    # 如果调用了chi() 会创建a,b变量,也就是两个小空间
    chi()
    (3)
    def chi():
        a = 10
        print(a)
    chi()
    print(a) # 在没有其他条件的情况下,外部不可以调用内部变量,所有报错
    (4)
    def print(b):
        pass
    a = 10
    def chi():
        print(a)
    chi()
    总结:
    从全局去找局部 -> 找不到
    局部去找全局 -> 可以找到
    (5)
    名称空间可以有无数个
    数据结构推荐:C严蔚敏

    内置名称空间第一层,全局名称空间是第二层,局部名称空间是第三层
    从第三层到第一层开始找
    (6)
    a=10
    b=20
    def 今天有是星期五了():
        pass
    今天有是星期五了()
    print(globals())
    #查看全局作用域中的内容
    #globals 全局作用域:内置+全局名称空间
    '''
    结果:
    {'__name__': '__main__', 
    '__doc__': None, 
    '__package__': None, 
    '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000170913EB438>, 
    '__spec__': None, 
    '__annotations__': {},
     '__builtins__': <module 'builtins' (built-in)>,
     '__file__': 'F:/Python_workspace_S18/day10 函数的进阶/04 名称空间和作用域.py', 
     '__cached__': None, 
     'a': 10, 'b': 20,
      '今天有是星期五了': <function 今天有是星期五了 at 0x0000017091391E18>}
    '''
    #自己写的全局变量:
    # 'a': 10, 'b': 20,
    #   '今天有是星期五了': <function 今天有是星期五了 at 0x0000017091391E18>}
    (7)
    def chi():
        a=20
        b=30
        # print(locals())     #查看当前作用域中的内容
        print(globals())
        # alex,老男孩儿, 武sir, 全局作用域中的内容,在这里不显示a和b了
        #我们可以知道不创建,在全局作用域内找不到局部作用域中的内容
    chi()
    
    '''
    结果:
    {'b': 30, 'a': 20}
    
    {'__name__': '__main__', 
    '__doc__': None, '__package__': None, 
    '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000026EB5D4B438>, 
    '__spec__': None, 
    '__annotations__': {}, 
    '__builtins__': <module 'builtins' (built-in)>, 
    '__file__': 'F:/Python_workspace_S18/day10 函数的进阶/04 名称空间和作用域.py', 
    '__cached__': None, 
    'chi': <function chi at 0x0000026EB5CF1E18>}
    
    '''
    # print(locals()) # 全局
    # print(globals()) # 全局
    3.函数的互相调用和函数的嵌套 
    (1)函数的互相调用
    def func1():
        print("我是神器的func1")
    def func2():
        func1()
        print("我是神器的func2")
    def func3():
        print("我是神器的func3")
        # func5()
    def func4():
        func3()
        print("我是神器的func4")
    def func5():
        func2()
        func3()
        print("我是神器的func5")
    def func6():
        func5()
        print("我是神器的func6")
        func3()
        func1()
    func6()

    结果:

    '''
    结果:
    我是神器的func1
    我是神器的func2
    我是神器的func3
    我是神器的func5
    我是神器的func6
    我是神器的func3
    我是神器的func1
    '''
    (2)函数的嵌套
    (2-1)
    def outer():
        def inner():
            print("我的天哪")
        print("还可以这样写???")
        inner()
    outer()
    
    '''
    结果:
    还可以这样写???
    我的天哪
    '''
    # inner() # 在全局不能找到局部的内容,所以不能直接写在外边
    (2-2)
    def func1():
        print("1")
        def func2():
            print("2")
            def func3():
                print("3")
            print("4")
            func3()
            print(5)
        print("6")
        func2()
        print("7")
    func1()
    View Code

    结果:

    1
    6
    2
    4
    3
    5
    7
    View Code

    4.nonlocal&global
    (1)
    global是在内部修改全局
    全局变量一般是不能随意的修改的
    a = 10
    def func():
        # 慎用.
        global a  # 重点记忆:global 表示从全局把一个变量引入到局部, 后面使用的a都是全局变量
        a += 10 # ?? a = a + 10 # 现在的a是全局的, 你现在视图改全局变量
        print("里面的打印",a)
    func()
    print("外面的打印", a)
    
    '''
    结果:
    里面的打印 20
    外面的打印 20
    '''
    (2)
    nonlocal  在局部, 寻找离他最近的外层的一个变量
    a = 50
    def func1():
        a = 10 # 局部,如果这里没有a=10,会报错
        def func2():
            nonlocal a # 不找全局,只能找外层函数中的, global找全局
            a += 10 # a = a + 10 python不让这么干
            print("func2", a)
        func2()
        print(a)
    func1()
    print(a)
    结果:
    func2 20
    20
    50
    (3)
    #不管是多少层.globals都是找全局里的
    #全局变量一般是不能随意的修改的

    #注意:nonlocal不能找全局变量
    # nonlocal 在局部,寻找离他最近的外层的一个变量

    # 如果没有nonlocal和global 查找的顺序: 自己, 上一层, 上一层, 上一层
    def func1():
        a=10   #局部
        def func2():
            nonlocal a
            a=30
            print('func2',a)
        func2()
        print(a)
    func1()
    
    '''
    结果:
    func2 30
    30
    '''

    (4)真假难辨,这种题都能做出来,还有什么题目不能做出来

    a = 1
    def fun_1():
        a = 2
        def fun_2():
            nonlocal a
            a = 3
            def fun_3():
                a = 4
                print(a)
            print(a)
            fun_3()
            print(a)
        print(a)
        fun_2()
        print(a)
    print(a)
    fun_1()
    print(a)

    结果:

    结果:
    1
    2
    3
    4
    3
    3
    1
    View Code
    (5)折叠调用
    def login():
        global flag
        uname = input("用户名:")
        upwd = input("密码:")
        if uname == "alex" and upwd == "123":
            flag = True
        else:
            flag = False
    def fatie():
        if flag == True:
            print("可以发帖")
        else:
            print("滚去登录")
    login()
    fatie()

    今日作业:

    2,写函数,接收n个数字,求这些参数数字的和。(动态传参)
    方法一:
    def digit_sum(*args):
        print(sum(args))
    digit_sum(1,2,3,4,5)
    
    方法二:
    def digit_sum(*args):
        sum=0
        for i in args:
            sum+=i
        print(sum)
    digit_sum(1,2,3,4,5)
    View Code
    3,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
    a=10
    b=20
    def test5(a,b):
    print(a,b)
    c = test5(b,a) #c代表的是返回值
    print(c)
    a是20
    b是10
    c是None
    
    结果是:
    20 10
    None
    View Code
    4,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
    a=10
    b=20
    def test5(a,b):
    a=3
    b=5
    print(a,b)
    c = test5(b,a)
    print(c)
    print(a,b)
    打印出来的结果
    a是3 b是5
    None
    a是10 b是20
    5,写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等),
    将每个实参的每个元素依次添加到函数的动态参数args里面.
    例如 传入函数两个参数[1,2,3] (22,33)最终args为(1,2,3,22,33)
    这里必须要对列表或者元组进行打散才可以
    def pa(*args):              #1
        # print(args)
        return args             #2
    # a=pa([1,2,3],(22,33))     #结果:([1, 2, 3], (22, 33))
    x=[1,2,3]                   #3
    y=(22,33)                   #4
    a=pa(*x,*y)                 #5
    print(a)                    #6
    6,写函数,传入函数中多个实参(实参均为字典),
    将每个实参的键值对依次添加到函数的动态参数kwargs里面.
    例如 传入函数两个参数{‘name’:’alex’} {‘age’:1000}
    最终kwargs为{‘name’:’alex’ ,‘age’:1000}
    #注意,必须要接受参数
    
    def a(**kwargs):
        return kwargs
    x={'name':'alex'}
    y={'age':1000}
    b=a(**x,**y)
    print(b)
    7, 下面代码成立么?如果不成立为什么报错?怎么解决?
    7.1
        a = 2
        def wrapper():
                print(a)
        wrapper()
    #正确
    
    7.2
        a = 2
        def wrapper():
                    a += 1
                print(a)
        wrapper()
    #错误,在赋值前引用全局变量a
    修改后的程序
    a = 2
    def wrapper():
        global a
        a += 1
        print(a)
    wrapper()
    
    7.3
    def wrapper():
                a = 1
                def inner():
                    print(a)
                inner()
        wrapper()
    #正确
    7.4
    def wrapper():
                a = 1
                def inner():
                    a += 1
                    print(a)
                inner()
        wrapper()
    #错误,在赋值前引用全局变量a
    
    #修改后的结果
    def wrapper():
        a = 1
        def inner():
            nonlocal a
            a += 1
            print(a)
        inner()
    wrapper()
    8,写函数,接收两个数字参数,将较小的数字返回.
    def func(a,b):
        if a>b:
            return b
        else:
            return a
    x=func(2,3)
    print(x)
    9,写函数,接收一个参数(此参数类型必须是可迭代对象),
    将可迭代对象的每个元素以’_’相连接,形成新的字符串,并返回.
    例如 传入的可迭代对象为[1,'老男孩','武sir']返回的结果为’1_老男孩_武sir’
    def func(x):
        s=''
        for i in x:
            i=str(i)
            s+=i +"_"
        return s.strip('_')
    a=func([1,'老男孩','武sir'])
    print(a)
    10,写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值}
    例如:min_max(2,5,7,8,4) 返回:{‘max’:8,’min’:2}(此题用到max(),min()内置函数)
    def func(*args):
        return {'max':max(args),'min':min(args)}
    a=func(*(2,5,7,8,4))
    print(a)
    11,写函数,传入一个参数n,返回n的阶乘
    例如:cal(7) 计算7*6*5*4*3*2*1
    def cal(n):
        if n==0:
            return 1
        return n * cal(n - 1)
    a=cal(3)
    print(a)
    12写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
    例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
    def puke():
        a=['红心','草花','梅花','黑桃']
        b=[2,3,4,5,6,7,8,9,10,'J','Q','K','A']
        lst=[]
        for i in b:
            for k in a:
                lst.append((k,i))
        return lst
    a=puke()
    print(a)
    13 有如下函数:
    def wrapper():
    def inner():
    print(666)
    wrapper()
    你可以任意添加代码,用两种或以上的方法,执行inner函数.
    方法一
    def wrapper():
        def inner():
            print(666)
        inner()
    wrapper()
    
    方法二
    def wrapper():
        def inner():
            print(666)
        return inner
    wrapper()()
    14相关面试题(先从纸上写好答案,然后在运行):
    1,有函数定义如下:
    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___


    2,(此题有坑)下面代码打印的结果分别是__[10,'a']___,__[123]___,___[10,'a']__.
    def extendList(val,list=[]):  #多次调用使用同一个列表
    list.append(val)     #把元素添加到列表,然后返回列表
    return list
    list1 = extendList(10)
    list2 = extendList(123,[])
    list3 = extendList('a')

    print('list1=%s'%list1)
    print('list2=%s'%list2)
    print('list3=%s'%list3)
    3, 写代码完成99乘法表.(升级题)
    1 * 1 = 1
    2 * 1 = 2 2 * 2 = 4
    3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
    ......
    9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
    '''
    双for循环实现:
    for i in range(1,10):
        for j in range(1,i+1):
            r=i*j
            print('%s*%s=%s'%(i,j,r),'  ',end='')
        print()











  • 相关阅读:
    Oracle 学习笔记4 SQL语言基础
    Oracle 学习笔记3 Sql Plus 命令
    连接扩展屏后,桌面上的图标自动跑到扩展屏上去了
    Oracle数据库基础知识
    ORACLE 学习笔记 2 Oracle 11g 体系结构
    EXCEL 连接Oracle 数据库
    虚拟机
    截取默写数据库无法识别的字符前几位的值
    c#的SerialPort在多线程环境下需要加锁
    32. 最长有效括号
  • 原文地址:https://www.cnblogs.com/studybrother/p/10084631.html
Copyright © 2011-2022 走看看