函数

动态参数

  • *args

     def sum(*args):
         '''
         任何参数都会被args以元组的方式接收
         '''
         print(type(args))  # result:<class 'tuple'>
         sum = 0
         for i in args:
             sum += i
         return sum
    
     print(sum(1, 2, 3))  # result:6
     print(sum(*[1, 2, 3]))  # result:6
     # 12,13行等价
     # * 表示将这个列表按照顺序打乱传入
  • **kwargs

     def info(**kwargs):
         '''
         参数都会被kwargs以字典的方式接收
         :param kwargs:
         :return:
         '''
         print(type(kwargs))  # result:<class 'dict'>
         for key in kwargs:
             print(key, kwargs[key], end=' ')
         print()
    
     info(name='张三', age=12, gender='男')
     info(**{'name': '李四', 'age': 14, 'gender': '女'})  # ** 将字典按顺序打乱传入
     # result:   name 张三 age 12 gender 男
     #           name 李四 age 14 gender 女

默认参数

  • 通过默认参数输出

     def name_sex_print(name, sex='男'):
         print('姓名:{},性别:{}'.format(name, sex))
    
     name_sex_print('小强')
     name_sex_print('小兵')
     name_sex_print('小红', '女')
     # result:
     # 姓名:小强,性别:男
     # 姓名:小兵,性别:男
     # 姓名:小红,性别:女
  • 默认参数陷阱

     def num_print(num_list=[]):
         num_list.append(1)
         print(num_list)
    
     num_print()
     num_print([])
     num_print()
     num_print()
    
     # result:
     # [1]
     # [1]
     # [1, 1]
     # [1, 1, 1]

    结论:如果默认参数的值是一个可变数据类型,那么每一次调用函数的时候,如果不传值就公用这个数据的资源

函数的引用

函数名实际上可以看做指向函数在内存中的引用(和C#中委托很相像)

  • 赋值

     def func1():
         print('print in func1')
    
     func2 = func1;
     func2()
     #result:
     # print in func1
  • 函数的传递

     def func1():
         print('print in func1')
    
     def func2(func):
         print('print in func2')
         func()
    
     func2(func1)
    
     # result:
     # print in func2
     # print in func1

命名空间

命名空间的概述

  • 内置命名空间

    1.python解释器一启动就可以使用的变量及函数存放在内置命名空间内

    2.内置的变量及函数在启动解释器的时候被加载进内存里

    3.不能使用局部和全局命名空间的函数及变量

  • 全局命名空间(自己写的非函数内部的代码)

    1.是在程序从上到下被执行的过程中依次加载进内存的

    2.放置了我们设置的所有变量名和函数名

    3.可以使用内置命名空间但不能使用局部命名空间中定义的变量及函数

  • 局部命名空间

    1.定义在函数内部

    2.当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个命名空间就又消失了

    3.可以使用全局及内置命名空间中的定义的变量及函数

三种命名空间的加载与取值顺序

  • 加载顺序

    内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:函数调用时才加载)

  • 取值顺序

    局部命名空间->全局命名空间->内置命名空间

作用域

作用域概述

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域

  • 全局作用域

    包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

  • 局部作用域

    局部名称空间,只能在局部范围(函数内部)生效

查看局部变量和全局变量

使用locals()和globals()函数可查看局部和全局变量

  • locals()

     def locals_func():
         b = 2
         c = 3
         print(locals())
    
     locals_func()
     # result:
     # {'b': 2, 'c': 3}
  • globals()

     a=1
     b=2
     print(globals())
     #result:
     # {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000001D67208>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/learning/python/test/0828/locals.py', '__cached__': None, 'a': 1, 'b': 2}

作用域链

  • 就近原则

    在函数内部使用一个变量时,会由近到远(由内而外)查找同名变量

     str = 'in globals'
    
     def fun1():
         str = 'in locals func1'
    
         def func2():
             str = 'in locals func2'
             print(str)
    
         func2()
    
     fun1()
     # result:
     # in locals func2
     str = 'in globals'
    
     def fun1():
         str = 'in locals func1'
    
         def func2():
             # str = 'in locals func2'
             print(str)
         func2()
    
     fun1()
     # result:
     # in locals func1
     str = 'in globals'
    
     def fun1():
         # str = 'in locals func1'
    
         def func2():
             # str = 'in locals func2'
             print(str)
    
         func2()
     fun1()
     # result:
     # in globals
  • nonlocal关键字

    使用要求:

    1.外部(非全局)必须有这个变量

    2.在内部函数声明nonlocal变量之前不能再出现同名变量

     def func1():
         a = 1
    
         def func2():
             nonlocal a
             a = 2
    
         func2()
         print(a)
    
     func1()
     # result:
     

闭包

闭包函数的定义

内部函数包含对外部作用域而非全局作用域名字的引用,该内部函数称为闭包函数

 def outer():
     a = 1

     def inner():
         print(a)
     return inner

 func = outer()
 func()

闭包函数的判断

可通过函数的__closure__属性判断该函数是否是一个闭包函数,若返回不是None,则就是闭包函数

def outer():
    a = 1
    def inner():
        b = a
        print(inner.__closure__)
    inner()
outer()
print(outer.__closure__)
#result:
# (<cell at 0x0000000000410108: int object at 0x000007FED797D420>, <cell at 0x0000000001DC82E8: function object at 0x00000000021CA730>)
# None

闭包的优缺点

  • 优点

    1.能够读取函数内部的变量

    2.让这些变量一直存在于内存中,不会在调用结束后,被垃圾回收机制回收

  • 缺点

    1.由于闭包会使函数中的变量保存在内存中,内存消耗很大,所以不能滥用闭包,解决办法是,退出函数之前,将不使用的局部变量删除

python基础(7)-函数&命名空间&作用域&闭包的更多相关文章

  1. python基础之函数详解

    Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...

  2. python基础——返回函数

    python基础——返回函数 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回.  我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_ ...

  3. python基础——匿名函数及递归函数

    python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x ...

  4. python基础——匿名函数

    python基础——匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便.  在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时 ...

  5. python基础——sorted()函数

    python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个d ...

  6. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  7. 八. Python基础(8)--函数

    八. Python基础(8)--函数 1 ● 函数返回布尔值 注意, 自定义的函数也可以是用来作逻辑判断的, 例如内置的startswith()等函数. def check_len(x):     ' ...

  8. Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器

    Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: ​ 1. 可以在局部作用域声明一 ...

  9. Python进阶(二)----函数参数,作用域

    Python进阶(二)----函数参数,作用域 一丶形参角度:*args,动态位置传参,**kwargs,动态关键字传参 *args: ​ 动态位置参数. 在函数定义时, * 将实参角度的位置参数聚合 ...

随机推荐

  1. 在SQL Server 2017 中,当Alwasyon group启用了DTC_SUPPORT = PER_DB, 会导致无法创建replicaiton.

    当Alwasyon group启用了DTC_SUPPORT = PER_DB, 会导致无法创建replicaiton.无法修改已经存在的replication. 原因: 当当Alwasyon grou ...

  2. 2D空间的OBB碰撞实现

    OBB全称Oriented bounding box,方向包围盒算法.其表现效果和Unity的BoxCollider并无二致.由于3D空间的OBB需要多考虑一些情况 这里仅关注2D空间下的OBB. 实 ...

  3. Intel Fortran 调用Delphi编制的DLL

    module link_cont interface subroutine I_FileOpenCont (ncase,ndata,lpool,xfiles) integer(kind=) :: nc ...

  4. 备份与还原ORACLE数据库(通过CMD命令执行)

    31.1:(若用程序调用cmd,则在备份和还原 末尾语句加上 2>&1 ,直接运行则不需要加) --备份:     1) exp SA/"""abc@123 ...

  5. mongodb应用

    一.概述 NoSQL,指的是非关系型的数据库.NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称.NoSQL用于超大规模数据的存储.(例如谷歌或Fa ...

  6. Python2.x与3.x版本区别

    Python2.x与3.x版本区别 1.print 函数 print语句没有了,取而代之的是print()函数. Python 2.6与Python 2.7部分地支持这种形式的print语法.在Pyt ...

  7. FasterRCNN 提升分类精度(转)

    近年来,随着深度学习的崛起,计算机视觉得到飞速发展.目标检测作为计算机视觉的基础算法,也搭上了深度学习的快车.基于Proposal的检测框架,从R-CNN到Faster R-CNN,算法性能越来越高, ...

  8. Beautiful Soup模块

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...

  9. 用lua编写wireshark插件分析自己定义的协议

    参见: https://yoursunny.com/study/IS409/ScoreBoard.htm https://wiki.wireshark.org/LuaAPI/TreeItem http ...

  10. Let's Encrypt泛域名SSL证书申请

    操作系统:CentOS 7 github:https://github.com/Neilpang/acme.sh 有中文说明: https://github.com/Neilpang/acme.sh ...