zoukankan      html  css  js  c++  java
  • python函数的动态传参.作用域与命名空间

    一.动态传参
    1.*表示动态传参. 可以接受所有的位置参数传参的时候自动的把实参打包成元组 交给形参
    def chi(*food):
        print(food)
    chi() # 动态传参可以不传参数
    chi(good_food = "胡辣汤") # 关键字传参
    chi("胡辣汤", "疙瘩汤", "西红柿鸡蛋汤")
    chi("大猪蹄子","大汉堡","薯条","圣代","雪顶","拿铁")
    
    2.** 表示接收关键字的动态传参接收到的内容放在字典里
    def chi(**food):
        print(food)
    chi(good_food = "哈哈", junk_food="呵呵", drink="吼吼")
    chi("大猪蹄子","大汉堡","薯条","圣代","雪顶","拿铁")
    1.顺序
    位置 > *args > 默认值参数 > **kwargs
    实参: 位置 > 关键字
    位置, *args, 默认值参数, **kwargs
    无敌传参
    顺序  位置 > *args > 默认值参数 > **kwargs
    def func(*args, **kwargs):
        print(args, kwargs)
    func(1,2,"哈哈",3,4,5,a=6,b=7,c=8,d=9, e=18 )
    
    lst = ["火腿肠","方便面","有调料包","被捏碎了", "韭菜", "大白菜"]
    def chi(*food): #  形参上的* : 动态接收位置参数
        print(food)
    # 把列表中的所有食物传递给chi
    chi(*lst) # 把一个列表或者元组或者字符串.打散成参数. 传递给形参
    
    2.*, ** : 在形参: 聚合, 实参: 打散
    dic = {"张无忌":"倚天屠龙记", "乔峰":"天龙八部", "郭靖":"射雕"}
    def da(**kwargs): # 动态传参. 接收关键字参数
        print(kwargs)
    # da(张无忌=dic['张无忌'])
    da(**dic)   # 把字典打散成关键字参数
    

    二.名称空间和作用域
    名称空间: 保存名字用的
    变量, 函数, 类

    1. 内置名称空间:python自己, print, input, len
    2. 全局名称空间: 你写的代码从上到下
    3. 局部名称空间: 函数, 类, 方法, 其他模块, 对象

    作用域
    全局作用域
    内置 + 全局
    局部作用域
    局部名称空间
    从局部找全局可以. 但是从全局找局部是不可以的

    globals() 查看全局作用域中的名字
    locals() 查看当前作用域中的名字

    a = 10
    def chi():
        a = 20
        print(a)
    
    print(a) # 10
    chi()   # 20
    print(a) # 10
    
    def print(*args):
        pass
        # print(args) # maximum recursion depth exceeded
    
    def func():
        print("呵呵")
    
    func()
    def chi():
        p = 30
        print(locals()) # {'p': 30}   locals()可以查看局部作用域中的内容
        print(p)
    chi()
    print(locals()) # 查看当前作用域中的名字
    print(globals())
    a = 10 # 全局
    b = 20
    print(globals()) # 查看全局作用域中(内置+全局)的内容
    

      

    3. 函数的嵌套(难点)
    每一层都会产生独自的名称空间

    例一
    # 一个套一个
    def outer():
        print("我是outer")
        # 在函数内部声明的函数, 只能在函数内部访问
        def inner():
            print('我是inner')
        inner()
        print("我是outer_end")
    outer()
    
    例二
    def fun2():
        print(222)
        def fun3():
            print(666)
        print(444)
        fun3()
        print(888)
    print(33)
    fun2()
    print(555)
    
    33 222 444 666 888 555
    

      


    4. nonlocal global
    global: 在局部引入全局的内容, 可以升华一个变量为全局变量
    nonlocal : 在局部, 引入上一层名称空间中的变量, 如果没有, 继续上一层

    1.global a  #直接从全局把变量引入进来,可以创建(升华)一个局部变量为全局变量
    例一
    a = 10
    def func():
        global a  # 直接从全局把变量引入进来
        a = 20
        # a = 20 # 并没有改变全局变量,   创建了一个自己的变量
        # 全局变量在局部, 可以用, 但是, 不能改
        # a = a + 10
        print(a)
    func()
    print(a)
    例二
    def func():
        global a # 可以创建(升华)一个局部变量为全局变量
        a = 30
    func()
    print(a)
    
    
    
    2.nonlocal 在局部, 引入上一层名称空间中的名字. 如果上一层没有, 继续上一层 .....
    例一
    def outer():
        a = 10
        def inner():
            nonlocal a
            a = 20
            print(a)
        print(a)  # 10
        inner()   # 20
        print(a)  # 20
    outer()
    例二
    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)
    
    # 答案1234331 

    三.作业

    1,写函数,接收n个数字,求这些参数数字的和。(动态传参)
    def num(*args):
        sum=0
        for i in args:
            sum+=i
        return sum
    print(num(1,2,3,4))
    
    2,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
    a=10
    b=20
    def test5(a,b):
            print(a,b)
    c = test5(b,a)
    print(c) #20 10没有返回值所以最后打印的值是空
    
    3,读代码,回答:代码中,打印出来的值a,b,c分别是什么?为什么?
    a=10
    b=20
    def test5(a,b):
        a=3
        b=5
        print(a,b) #3  5
    c = test5(b,a)
    print(c	) # 空
    print(a,b) #10 20
    4,写函数,传入函数中多个实参(均为可迭代对象如字符串,列表,元祖,集合等),将每个实参的每个元素依次添加到函数的动态参数args里面.
    例如 传入函数两个参数[1,2,3] (22,33)最终args为(1,2,3,22,33)
    def func(lis,tu):
        for i in list(tu):
            lis.append(i)
        return tuple(lis)
    print(func([1,2,3],(22,33)))
    
    5,写函数,传入函数中多个实参(实参均为字典),将每个实参的键值对依次添加到函数的动态参数kwargs里面.
    例如 传入函数两个参数{‘name’:’alex’} {‘age’:1000}最终kwargs为{‘name’:’alex’ ,‘age’:1000}
    def func(**kwargs):
        print(kwargs)
    func(**{"name":"alex"},**{"age":1000})
    
    
    6, 下面代码成立么?如果不成立为什么报错?怎么解决?
    7.1
    a = 2
    def wrapper():
            print(a)
    wrapper()
    成立
    7.2
    a = 2
    def wrapper():
              a += 1
            print(a)
    wrapper()
    不成立,局部空间无法直接调用全局空间中的变量
    7.3
    def wrapper():       #第一步def直接调用,第二定义,第三执行,第四部
            a = 1
            def inner():
                print(a)
            inner()
    wrapper()
    可执行
    7.4
    def wrapper():
            a = 1
            def inner():
                a += 1
                print(a)
            inner()
    wrapper()
    局部空间的变量不能直接调用和改变外层变量
    8,写函数,接收两个数字参数,将较小的数字返回.
    def func(a,b):
        if  a>b:
             return b
         else:
             return a
         print(func(3,4))
        return a if a<b else b
    print(func(3,4))
    方案二
    def func(a,b):
         return a if a<b else b
    print(func())
    9,写函数,传入n个数,返回字典{‘max’:最大值,’min’:最小值}
    例如:min_max(2,5,7,8,4) 返回:{‘max’:8,’min’:2}(此题用到max(),min()内置函数)
    def func(*args):
        print(min(args))
        print(max(args))
        return {'最大值': max(args),"最小值":min(args)}
    print(func(2,4,7,8.0))
    10,写函数,传入一个参数n,返回n的阶乘
    例如:cal(7)  计算7*6*5*4*3*2*1
    def func(n):
        s=1
        for i in range(1,n+1):
            s*=i
        return s
    print(func(5))
    
    11写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组
    例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
    pai=[]
    s=["红桃","方块","黑桃","梅花"]
    t=["A",'2','3','4','5','6','7','8','8','10','J','Q','K']
    for i in s:
        for j in t:
           pai.append((i,j))
    print(pai)
    print(len(pai))
    12 有如下函数:
    def wrapper():
        		def inner():
            		print(666)
    	wrapper()
    
    你可以任意添加代码,用两种或以上的方法,执行inner函数.
    def wrapper():
        def inner():
            print(666)
        # return inner() #1
        # inner()        #2
    wrapper()
    

      

  • 相关阅读:
    高德地图的使用点标记、折线标记
    vue 过滤器filter(全面)
    vue cli4.0 快速搭建项目详解
    vue cli3.0快速搭建项目详解(强烈推荐)
    路由传参的三种方法
    router-link 返回上页 和 新窗口打开链接
    Django REST framework+Vue 打造生鲜超市(一)
    Android笔记:波纹按钮
    简单更换博客园背景
    SUID,SGID和SBIT
  • 原文地址:https://www.cnblogs.com/liucsxiaoxiaobai/p/9892135.html
Copyright © 2011-2022 走看看