函数参数/作用域/args/kwargs

1.参数

1.1参数基本知识

  • 任意个数

  • 任意类型

    func("1",True)

1.2位置传参(调用函数并传入参数)

def func(a1,a2):
pass
func(1)#缺少位置参数
func(1,2,3)#多了位置参数

1.3关键字传参

def func(a1,a2):
pass
func(a2=99,a1=2)#根据形参名字传入值

1.4关键字传参和位置传参可以混合使用

注意位置参数在前 关键字参数在后,总和参数个数要和函数参数个数相等

def func(a1,a2,a3):
pass
func(1,a2=3,a3=9)#根据形参名字传入值
func(a1=1,3,9)#报错 关键字参数在前
func(1,a1=2,a3=9)#报错 a1得到多个值
func(1,a2=0,9)#报错 关键字在前

1.5默认参数[定义]

参照open()函数

注意:如果默认值是可变类型
def func(a1,a2=9)#a2可传可不传
pass
func(1,2)#给a2传新值 覆盖默认值
func(1)#默认a2=9

1.6 万能参数(*args)—>arguments 多个参数

  • args:接受n个位置参数

  • 可以接受任意类型参数,并转换为元组

  • 调用时候无*

    #args循环遍历每个位置参数 一个一个放入args中 并转换为元组
    def func(*args):
    print(args) func(1) # (1,)
    func(1, 2, 3) # (1,2,3)
    func(1, 2, [1, 23], "True", "alex")
    func((1, 2, 3))
    # 该元组作为一个单元素传入 -->元组嵌套((1,2,3),))
    #(1,)
    # (1, 2, 3)
    # (1, 2, [1, 23], 'True', 'alex')
    # ((1, 2, 3),))
  • 调用时有:直接将后面的位置参数转换为元组

    def func(*args):
    print(args) func(*(1, 2, 3)) # 打散传入元组 变成多个变量传入args -->(1,2,3)
    func(*[1, 2, 3]) # args原理是 循环遍历每个元素 添加到元组中(1,2,3)
    #(1, 2, 3)
    #(1, 2, 3)
  • 只能用位置传参


    def func(a1,*args,a2):
    pass
    func(1,2,3,4,a2=0)#a2只能关键字传参
    #a1=1 args=(2,3,4)

1.7键值万能参数(**kwargs)

  • 接收任意个关键字参数

    def func(**kwargs):
    print(kwargs) func(k1=1,k2="gao")#kwargs={"k1":1,"k2":"gao"}
  • 调用时有*

    def func(**kwargs):
    print(kwargs)
    func(**{"k1":1,"k2":"gao"})#kwargs=kwargs={"k1":1,"k2":"gao"}
  • 调用时候无*

    def func(**kwargs):
    print(kwargs)
    func(k1=1,k2="gao")#kwargs={"k1":1,"k2":"gao"}
  • 只能用关键字传参

  • 综合应用

    def func(*args,**kwargs):
    print(args,kwargs)
    func(*[1,2,3],k1=2,k5=9,k19=999)#(1,2,3) {"k5":9,"k19":999}
    func(*[1,2,3],**{"k1":"1","k2":2})#(1,2,3){"k1":"1","k2":2}
    func(11,22,*[1,2,3],k11=333,k33="bb")#(11,22,1,2,3) {"k11":333,"k3":"bb"}
    #5.看代码写结果
    
    # def func(name,age=19,email='123@qq.com'):
    # pass # a. 执行 func('alex') ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #可行 name=alex age=19 email=123@qq.com # b. 执行 func('alex',20) ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #可行 name:alex age:20 email:123@qq.com # c. 执行 func('alex',20,30) ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #可行 name:alex age:20 email:30 # d. 执行 func('alex',email='x@qq.com') ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #可行 name:alex age:19 email:x@qq.com # e. 执行 func('alex',email='x@qq.com',age=99) ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #alex 99 x@qq.com # f. 执行 func(name='alex',99) ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #不可行 关键字参数在前 位置参数在后 # g. 执行 func(name='alex',99,'111@qq.com') ,判断是否可执行,如可以请问 name、age、email 的值分别是?
    #不可行
练习
c. 请将执行函数,并实现让args的值为 ([11,22],33) 且 kwargs的值为{'k1':'v1','k2':'v2'}
def func(*args,**kwargs):
print(args)
print(kwargs)
val=func([11,22],33,k1="v1",k2="v2")
val1=func(*[[11,22],33],k1="v1",k2="v2")
#第一种:传入多个位置参数 循环遍历加入args后 变成元组
#第二种:类似强制转换方式 tuple([[11,22],33])将*后面的转换为元组 ([11, 22], 33)
{'k1': 'v1', 'k2': 'v2'}
#————————————————————————————————————————————————————————
([11, 22], 33)
{'k1': 'v1', 'k2': 'v2'}

2.作用域

2.1全局作用域

2.1局部作用域

2.3总结

  • 一个函数是一个作用域

    def func():
    x=9
    print(x)
    func()
    print(x)#报错
  • 作用域中查找数据规则:优先自己作用域查找,再去自己父级作用域查找,直到找到全局作用域为止

    x=10
    def func():
    x=9
    print(x)#9
    func()
    print(x)#10
    • 注意:函数的调用顺序
    x = 10
    
    def func():
    x = 8
    print(x) # 8 def func2():
    x = 999
    print(x) # 999 print(x) # 8
    func2() func() # 执行 8 8 999
    #
    x = 10 def func():
    x = 8
    print(x) # 8 def func2():
    x = 999
    print(x) # 999 print(x) # 8
    func2() #
    print(x) # 8
    #func2函数执行完毕后 内部局部变量x被销毁掉 所以不会对自己内部的变量进行重新赋值 func() # 执行8 8 999 8
  • 子作用域中只是读取或者修改【列表类型等可变类型】父级作用域的值,【默认】无法为父级的变量重新赋值 ,子作用域只是在自己内部重新开辟一块空间,为该变量赋值。但是通过添加global /nonlocal 关键字可以为父级的指定变量重新赋值

    NUM=[1,2,3]
    def func():
    #NUM.append(999)#可以修改父级可变类型的值
    print(NUM)#[1,2,3,999]
  • global :找到全局作用域中的变量

    name = "gao"
    
    def func():
    name = "chen"
    print(name) # chen def func2():
    global name # 找到全局变量name
    name = "gao_chen"#为全局变量的name重新赋值
    print("val:" + name) # func2内部的name gao_chen print(name) # func 内部的chen
    func2() #
    print(name) # chen func() # 函数执行
    print(name) # gao_chen 内部函数通过global修改lname的值 #chen
    #chen
    #val:gao_chen
    #chen
    #gao_chen
  • nonlocal :找到父级作用域中指定变量 ,【必须是父级作用域 不包括全局作用域】

  • 如果父级(父级的父级…..)作用域中不存在 则报错

    name = "gao"
    
    def func():
    name = "chen"
    print(name) # chen def func2():
    nonlocal name # 找到父级作用域的name(func中的name)
    name = "gao_chen"
    print("val:" + name) # gao_chen print(name) # chen
    func2() #
    print(name) # gao_chen func() #
    print(name) # gao
    name = "gao"
    
    def func():
    print(name) def func2():
    nonlocal name #报错 可以是父级,父级的父级 但是不能是全局
    name = "gao_chen"
    print("val:" + name) print(name)
    func2()
    print(name) func() #
    print(name) #SyntaxError: no binding for nonlocal 'name' found name = "gao" def func():
    name = "hahahaha"
    print(name) # hahahaha def func2():
    print("val:" + name) # val:hahahaha def inner():
    nonlocal name#不报错 父级的父级的name
    name = "test" inner() print(name) # hahahaha
    func2()
    # 其内部函数inner()也会被func2执行 因为inner()内部定义nonlocal关键字
    # 所以父级作用域的func()函数的name会被重新赋值
    print(name) # test 被局部修改 func() #
    print(name) # gao 没有被改变
    #hahahaha
    #hahahaha
    #val:hahahaha
    #test
    #gao
  • 全局变量尽量大写

3.总结

  1. 函数类型

    • def func()
    • def func(a1,a2=None)
    • def func(*args,**kwargs)
  2. 函数参数

    • 形参

      • def func()
      • def func(a1,a2=None)
      • def func(*args,**kwargs)
    • 实参

      • 位置传参

      • 关键字传参

      • 传参规则: 位置参数在前,关键字参数在后

      • 默认参数

      • 万能传参

        • *args:位置传参—>可传任意类型 ——>都会转为元组

          • 调用函数时候有*
          • 调用函数时候没有*
        • **kwargs:关键字传参——>转为字典

          • 调用函数时候有*
          • 调用函数时候没有*
  3. 作用域

    • 局部和全局

    • 一个函数一个作用域

    • 作用域查找规则:

      • 自己没有父级 父级再找父级,父级都没有找全局
      • 自己->父级->父级->全局[读/修改(可变)]
      • 子作用域内不能为父级作用域内的变量重新赋值 只能读取或者修改[可变类型]
    • 重新赋值:

      • global
      • nonlocal
  4. 函数嵌套

day10 参数args kwargs 作用域的更多相关文章

  1. python之动态参数 *args,**kwargs和命名空间

    一.函数的动态参数 *args,**kwargs, 形参的顺序1.你的函数,为了拓展,对于传入的实参数量应该是不固定,所以就需要用到万能参数,动态参数,*args, **kwargs 1,*args ...

  2. python之动态参数 *args,**kwargs(聚合,打散--转载

    转自https://www.cnblogs.com/ellisonzhang/p/10243122.html 一.函数的动态参数 *args,**kwargs, 形参的顺序 1.你的函数,为了拓展,对 ...

  3. python可变参数*args, **kwargs

    python可变参数*args, **kwargs def foo(* args, ** kwargs): print ' args = ',  args print ' kwargs = ',  k ...

  4. python之动态参数 *args,**kwargs(聚合,打散)

    一.函数的动态参数 *args,**kwargs, 形参的顺序1.你的函数,为了拓展,对于传入的实参数量应该是不固定,所以就需要用到万能参数,动态参数,*args, **kwargs 1,*args  ...

  5. 动态参数(*args,**kwargs),命名空间和作用域,global和nonlocal,函数的嵌套

    1. 动态参数 位置参数的动态参数: *args 关键字参数的动态参数 : **kwargs 顺序: 位置,*args,默认值,**kwargs 在形参上*聚合, **聚合 在实参上*打散, **打散 ...

  6. python 中参数*args, **kwargs

    def func(*args, **kwargs): print 'args : ', args print 'kwargs :', kwargs def test(): func(1,2,'x',' ...

  7. python 位置参数和关键字参数 *args **kwargs

    #!/usr/bin/env pythondef foo(*args,**kwargs): print('args: {0}'.format(args)) print('kwargs {0}'.for ...

  8. python函数参数*args **kwargs

    毕业多年,把C++都就饭吃了....今天居然在纠结什么是形参什么是实参..... 定义函数里面写的参数就是形参,因为没有内存占用,实际调用时写的参数就是实参,因为有内存占用和传值 然后就是位置参数,可 ...

  9. 函数动态参数 *args **kwargs

    def f1(*args,**kwargs): print(args,type(args)) print(kwargs,type(kwargs))li = [11,22,33]dic = {'k1': ...

随机推荐

  1. Unity录音

    上周做过Unity录音,(不知道的可以到网上查找一下,代码挺多的),不过只能录制麦克风的声音,项目需要同时录制背景音和麦克风传进去的声音,经过探索,现已可以录制: 首先需要知道,即使用电脑录音,想录制 ...

  2. C#中自定义高精度Timer定时器的实例教程

    Timer 用于以用户定义的事件间隔触发事件.Windows 计时器是为单线程环境设计的,其中,UI 线程用于执行处理.它要求用户代码有一个可用的 UI 消息泵,而且总是在同一个线程中操作,或者将调用 ...

  3. 第三章 熟悉常用的HDFS操作

    一.Hadoop提供的Shell命令完成相同任务: 1.在本地Linux文件系统的“/home/hadoop/”目录下创建一个文件txt,里面可以随意输入一些单词. mkdir hadoop 在本地查 ...

  4. 使用labelme制作自己的数据集

    # python3 conda create --name=labelme python=3.6 source activate labelme # conda install -c conda-fo ...

  5. C语言文件(例题及要点)

    char str[100] = "HELLOhello 123456789ABCD abcd!"; FILE *fp1, &fp2;//文件指针 fp1 = fopen(& ...

  6. Java小目标

    看了智联.内推和拉勾这三个招聘网站,除了智联外,其它招聘网站对岗位要求的描述都比较专业.大部分公司都要求会一些HTML5.JS,SSH等前端技术,所有公司都要求会使用Oracle.MySQL等数据库, ...

  7. 如何将Excel转换成Markdown表格[转]

    在这篇文章中,我将告诉你如何快速的将Excel转换为markdown表格,以及如何将Google Docs,Numbers,网页中的表格或其他类似Excel的程序数据转换为Markdown表格 你可能 ...

  8. IDEA新建项目时,没有Spring Initializr选项

    换了台新电脑,然后重新安装了Intellij IDEA,创建spring boot项目的时候找不到Spring Initializr选项了. 然后百度了下,发现有前辈做出了回答,就复制存到了自己随笔里 ...

  9. P3957 跳房子

    题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一条直线上.每个格子内 ...

  10. js 获取字符串中所有的数字和汉字

    var re1 = /(\d{1,3})+(?:\.\d+)?/g var re2 = /[\u4e00-\u9fa5]{2,}/g var str="11我22们33两个"; v ...