今天书接昨天的函数继续去学习了解:

昨天说到函数的动态参数。

1、函数的【动态参数】

*args 动态参数,万能参数
args接受的就是实参对应的所有剩余的位置参数,并将其放在元组( )中。 def func(x, y, z, *args):
print(x, y, z)
print(args) func(1, 2, 'a', 'b', 'c', 34) 1 2 a
('b', 'c', 34)
**kwargs 动态参数
将非位置对应的所有的关键字参数放到一个字典{ }中。
(排除形参中位置参数对应的实参中的关键字参数)
def func(x, y, z, *args, sex='男', **kwargs):
print(x, y, z)
print(args)
print(sex)
print(kwargs) func(1, 2, 'a', 'b', 'c', 34, m='yue', n=12, sex='女', p='r') 1 2 a
('b', 'c', 34)

{'m': 'yue', 'p': 'r', 'n': 12} 从形参的角度来看,它们的顺序应为:
位置参数在最前,*args次之,
默认参数因为形式上是关键字参数的式样故要排在*args后,而要在**kwargs之前。
(位置参数,*args,默认参数,**kwargs)

2、函数中【*和**的魔法运用】

在函数的调用(执行)时,*加一个可迭代对象(列表,元祖,字符串,字典等)代表解包,

(列表元祖打散成列表中的每个元素,字符串打散成每个字符,字典打散成每个键)

并将元素一 一添加进args。

如下例:

def func(*args):
return args
l1 = [1, 2, 30]
l2 = [1, 2, 33, 21, 45, 60]
# 要求将l1 和 l2 转化成元祖,
# 并且里面包含所有l1和l2的每一个元素,相同元素也得重复。
# 解:
tu = func(*l1, *l2)
print(tu) (1, 2, 30, 1, 2, 33, 21, 45, 60) 也可以简单理解成*是求可迭代对象的每一个元素。 而在函数的定义时,*args代表的是聚合(打包成元祖) **运用只限于字典(因它存在有键值对,可两两对应上),
同样在函数的调用执行时,**dict(一个字典对象),代表将字典所有的键值对放到kwargs字典里。
(解包打散字典) 例:
def func(**kwargs):
return kwargs
dic = {'name':'tiele', 'age':18, 'hobby':'下棋'}
dic2 = {'name2':'mao', 'age2':5, 'hobby2':'晒太阳'}
# 字典的键得是唯一,如果两个字典同键虽然不同值,执行下面函数的**运用也会报错
dic3 = func(**dic, **dic2)
print(dic3) {'name': 'tiele', 'age': 18, 'hobby2': '晒太阳', 'hobby': '下棋', 'age2': 5, 'name2': 'mao'} 在函数定义时,**kwargs代表的是聚合(成字典)

3、全局命名空间、局部命名空间、内置命名空间

名称空间:放置变量与对应的值(有的还有内存地址对应)的关系;

全局命名空间,放置变量与对应的值(有的还有内存地址对应)的关系的名称空间。

当执行函数的时候,内存开辟出一个临时名称空间(又叫局部命名空间),存放该函数内的变量与值的关系。

随着函数的执行完毕,临时名称空间也随之关闭。

内置名称空间,(python的内置函数),所有的内置函数等存储的空间。

4、顺序与函数的嵌套

加载顺序:

内置名称空间--->全局名称空间--->(函数执行时)--->局部名称空间。

取值顺序:

刚好与加载顺序相反,优先级为:

局部名称空间--->全局名称空间--->内置名称空间。

函数的嵌套:

函数在被调用的时候才执行;函数里面同样代码遵循从上至下依次执行;

5、作用域

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

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

局部作用域:局部名称空间,只能在局部范围内生效。

由作用域引申出两个函数方法globals()和locals()

例:

def func():
a = 33
b = 22
print(locals())
print(globals()) func()
c = 40
print(locals()) {'a': 33, 'b': 22}
{'__name__': '__main__', '__spec__': None, 'func': <function func at 0x0000000000755488>, '__builtins__': <module 'builtins' (built-in)>,
'__cached__': None, '__file__': 'E:/Python/day10/笔记.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000000066E048>,
'__doc__': None, '__package__': None} {'__file__': 'E:/Python/day10/笔记.py',
'__name__': '__main__', '__spec__': None,
'__builtins__': <module 'builtins' (built-in)>,
'__doc__': None, 'c': 40,
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000000009AE048>,
'__cached__': None, '__package__': None,
'func': <function func at 0x0000000000D85488>} 由上例可以看到,函数中locals存储的是{'a': 33, 'b': 22}

因为它的作用域是在局部命名空间中,所以它存储的变量和值并不多,而在函数之外再打印的locals就不同了,它的作用域扩大了,但是不包括局部,所以里面的值里可以找到'c':40而找不到a,b的值。

在函数中使用locals()方法可以很方便返回在这个临时命名空间作用域中所有的变量的值,呈字典返回,所以还是有它常用到的地方的。

global关键字,nonlocal关键字:

global:

1、声明一个全局变量。

2、在局部作用域想要对全局作用域的全局变量进行修改时,需要用到global(限于字符串,数字)。

例:

a = 2
def func():
a = 5
func()
print(a) #这时候a返回的是2 a = 2
def func():
global a
a = 5
func()
print(a) #使用了global后返回的是5 注:对可变数据类型(list,dict,set)可以直接引用不用通过global。 li = [1,2,3]
dic = {'a':'b'} def change():
li.append('a')
dic['q'] = 'g'
print(dic)
print(li)
change()
print(li)
print(dic) {'a': 'b', 'q': 'g'}
[1, 2, 3, 'a']
[1, 2, 3, 'a']
{'a': 'b', 'q': 'g'}

nonlocal:

  1、不能修改全局变量。

  2、在局部作用域中,对父级作用域(或者更外层作用域非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。

def add_b():
b = 42
def do_global():
b = 10
print(b)
def dd_nonlocal():
nonlocal b
b = b + 20
print(b)
dd_nonlocal()
print(b)
do_global()
print(b) add_b() 10
30
30
42

【补充】:

python是用命名空间来记录变量的轨迹的,命名空间是一个dictionary,键是变量名,值是变量值。

当一行代码要使用变量 x 的值时,Python 会到所有可用的名字空间去查找变量,按照如下顺序:

1)局部名字空间 - 特指当前函数或类的方法。

如果函数定义了一个局部变量 x, 或一个参数 x,Python 将使用它,然后停止搜索。

2)全局名字空间 - 特指当前的模块。如果模块定义了一个名为 x 的变量,函数或类,Python 将使用它然后停止搜索。

3)内置名字空间 - 对每个模块都是全局的。作为最后的尝试,Python 将假设 x 是内置函数或变量。

python的全局名字空间存储在一个叫globals()的dict对象中;

局部名字空间存储在一个叫locals()的dict对象中。

我们可以用print (locals())来查看该函数体内的所有变量名和变量值。

end

铁乐学Python_day10_函数2的更多相关文章

  1. 铁乐学python_day10_作业

    1.继续整理函数相关知识点,写博客. 2.写函数,接收n个数字,求这些参数数字的和.(动态传参) def sum_n(*args): sum = 0 for i in args: sum += i r ...

  2. 铁乐学Python_day09_函数

    今天我们来学习函数. 产生的原由,若没有函数,会显得重复代码多,可读性差,也会造成重复造轮子的情景. 故产生了函数,用来封装好一个功能,它是以功能为导向的. 1.[函数的样式] 例如自己定义一个函数: ...

  3. 铁乐学python_Day44_IO多路复用

    目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO ...

  4. 铁乐学python_Day43_协程

    铁乐学python_Day43_协程 引子 之前我们学习了线程.进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位. 按道理来说我们已经算是把cpu的利用率提高很多了. ...

  5. 铁乐学python_Day42_线程池

    铁乐学python_Day42_线程池 concurrent.futures 异步调用模块 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor: ...

  6. 铁乐学python_Day42_锁和队列

    铁乐学python_Day42_锁和队列 例:多个线程抢占资源的情况 from threading import Thread import time def work(): global n tem ...

  7. 铁乐学python_Day39_多进程和multiprocess模块2

    铁乐学python_Day39_多进程和multiprocess模块2 锁 -- multiprocess.Lock (进程同步) 之前我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发 ...

  8. 铁乐学python_Day38_多进程和multiprocess模块1

    铁乐学python_Day38_多进程和multiprocess模块1 [进程] 运行中的程序就是一个进程. 所有的进程都是通过它的父进程来创建的. 因此,运行起来的python程序也是一个进程,那么 ...

  9. 铁乐学Python_Day34_Socket模块2和黏包现象

    铁乐学Python_Day34_Socket模块2和黏包现象 套接字 套接字是计算机网络数据结构,它体现了C/S结构中"通信端点"的概念. 在任何类型的通信开始之前,网络应用程序必 ...

随机推荐

  1. Maven可以提交到官方公共仓库maven.org

    参考http://central.sonatype.org/pages/ossrh-guide.html这个网址的操作,即可提交到maven.org. 这里有具体的实践方法:http://blog.c ...

  2. 2019.2.1 现有vue-cli项目引入ESLint

    ESLint 不管是多人合作还是个人项目,代码规范是很重要的.这样做不仅可以很大程度地避免基本语法错误,也保证了代码的可读性. 可能在早期建立项目的时候,因为一些原因没有引入eslint.单元测试等, ...

  3. C#语法之扩展

    扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.这是msdn的描述.上面几句 ...

  4. C# WebBrowser设置代理

    WebBrowser控件是基于IE浏览器的,所以它的内核功能是依赖于IE. code: class IEProxy { //设置代理选项 private const int INTERNET_OPTI ...

  5. oracle 父子关系

    语句递归查找父子关系语句 表结构及数据 1.通过根节点遍历子节点 select t.*,LEVEL from Test2 t START WITH t.parentid=0 CONNECT BY PR ...

  6. Node.js Express 框架2

    文件上传 以下我们创建一个用于上传文件的表单,使用 POST 方法,表单 enctype 属性设置为 multipart/form-data. index.html <html> < ...

  7. 【JavaScript 从零开始】变量作用域

    变量作用域 一个变量的作用域(scope)是程序源代码中定义这个变量的区域. 全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的.然而在函数内声明的变量只是函数体内有定义. 他 ...

  8. golang chan 发送接收测试数据

    测试代码: package main import (     "fmt"     "time" ) const (     num = 10000000  / ...

  9. win32FTP程序设计

    掌握socket基于事件机制的网络程序设计,掌握多线程技术的FTP Server端设计方法,掌握FTP标准基本协议及其程序的实现,掌握文件内容的网络传输设计方法. 利用CFtpServer类接收和解析 ...

  10. 由Leetcode详解算法 之 动态规划(DP)

    因为最近一段时间接触了一些Leetcode上的题目,发现许多题目的解题思路相似,从中其实可以了解某类算法的一些应用场景. 这个随笔系列就是我尝试的分析总结,希望也能给大家一些启发. 动态规划的基本概念 ...