函数

动态参数

  • *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. idea maven 集成多模块 module

    首先第一步创建 顶级项目  也就是父项目 在创面那部中 不管你勾不勾 create from 那个选项 都无所谓,最终创建的项目要全删的 ,只保留pom.xml 父项目结构 接下来 创建子项目  也是 ...

  2. Python 词典增加和删除

    增加 dict 里面的属性,必须先初始化 key,然后使用 append 添加值 #!/usr/bin/python3 message = dict() #message = { # "10 ...

  3. Java反射+简单工厂模式总结

    除了 new 之外的创建对象的方法 通过 new 创建对象,会使得程序面向实现编程,先举个例子,某个果园里现在有两种水果,一种是苹果,一种是香蕉,有客户想采摘园子里的水果,要求用get()方法表示即可 ...

  4. go对json对象的生成和解析

    https://blog.csdn.net/benben_2015/article/details/78917374

  5. PXE(preboot execution environment):【网络】预启动执行环节:安装 debian 9系列:成功

    PXE 安装的必要点和之前一样. 这里只着重说一下debian系列 特殊的地方: 第一:Release.gpg问题 该问题解决方式一:要求官方的dvd.cd中提供,貌似不太可能实现...... 该问题 ...

  6. .net读取Excel转datatable、.net读取的Excel存在合并单元格并且转成datatable

    项目中经常会遇到Excel导入数据,Excel的模板会可能是存在合并单元格的,模板如下图所示 读取时需要填充合并单元格的值,转成datatable单元格值时,填充合并单元格的值,如下图所示: 合并单元 ...

  7. Oracle数据库自带表空间

    需求:需要整理现场用户创建的表空间以及其存储数据,进行规范化管理.在整理用户现场建立的表空间时,需要排除掉非用户创建的表空间,所有首先需要那些表空间是用户创建的,那些是Oracle自带的. 本机测试建 ...

  8. Tensorflow中神经网络的激活函数

    激励函数的目的是为了调节权重和误差. relu max(0,x) relu6 min(max(0,x),6) sigmoid 1/(1+exp(-x)) tanh ((exp(x)-exp(-x))/ ...

  9. unable to create ...erroractionpreference....

    Docker on windows 10 can't startup after deleting MobyLinuxVM in Hyper-V manually 重新启动hyper-v就可以解决了

  10. codeforces 1106 E

    显然是dp啊,dp[i][j]表示到时间i打扰了j次的最小收益 显然要排序,官方题解说set没看懂,优先队列就行啊. 按照时间排序,显然这样扫的话可以保证当前时间点的点在优先队列里吧, 然后有打断和不 ...