一.函数的动态的动态参数

动态参数分为两种:动态接收位置参数、动态接收关键字参数。

1.*args  位置参数动态传参

#  顺序: 位置参数=>*args(arguments) => 默认值参数
# * 在这里表示接收位置参数的动态传参, 接收到的是元组
def chi(name,*food, location="天津"): # 参数名是food *表示动态传参
print(location)
print(name+"要吃", food) chi("juan","驴打滚","二姑包子","桂顺斋","长春") #长春
#juan要吃("驴打滚","二姑包子","桂顺斋")

动态接收参数的时候要注意:动态参数必须在位置参数后面。具体请看下面几个示例:

 def chi(*food, a, b):
print("我要吃", food, a, b)
chi("大米饭", "小米饭", "黄瓜", "茄子")
# 这时程序会报错,因为前面传递的所有位置参数都被*food接收了,a和b永远接收不到参数
# TypeError: chi() missing 2 required keyword-only arguments: 'a' and 'b' # 所以上例可以改成以下代码
def chi(*food,a,b):
print("我要吃",food,a,b)
chi("大米饭","小米饭",a="黄瓜",b="茄子") # 必须用关键字参数来指定
# 这时候a和b就有值了,但是这样写的话位置参数就不能用了, # 所以,我们要先写位置参数,然后再用动态参数
def chi(a,b,*food):
print("我要吃",a,b,food)
chi("大米饭","小米饭","馒头","面条")
# 结果为:我要吃 大米饭 小米饭 ('馒头', '面条')
# 前面两个参数用位置参数来接收,后面的参数用动态参数接收
def chi(a,b,c="馒头",*food):
print(a,b,c,food)
chi("香蕉","菠萝") # 香蕉 菠萝 馒头 ()默认值生效
chi("香蕉","菠萝","葫芦娃") # 香蕉 菠萝 葫芦娃() 默认值不生效
chi("香蕉","菠萝","葫芦娃","口罩") # 香蕉 菠萝 葫芦娃("口罩",)默认值不生效
# 我们发现默认值参数写在动态参数前面,默认值只有一种情况可能会生效。
# 即默认值生效时,其后的动态参数接收的参数一定是0个 def chi(a,b,*food,c="娃哈哈"):
print(a,b,food,c)
chi("香蕉","菠萝") #香蕉 菠萝 ()娃哈哈 你默认值生效
chi("香蕉","菠萝","葫芦娃") #香蕉 菠萝 ("葫芦娃",) 娃哈哈 默认值生效
chi("香蕉","菠萝","葫芦娃","口罩") #香蕉 菠萝 ("葫芦娃","口罩")娃哈哈 默认值生效
# 将默认值参数放在动态参数之后,我们发现所有的默认值都生效了,
# 这时候如果不给出关键字传参,那么你的默认值是永远都生效的。

综上可得参数顺序:位置参数,*args(动态接收位置参数),默认值参数

2,动态接收关键字参数   **kwargs
在python中可以动态传参,但是*args这种情况只能接收位置参数,无法接收关键字参数 使用关键字参数的动态传参:就是用**kwargs来接收动态关键字参数,具体示例如下:
    def func(**kwargs):
print(kwargs)
func(a=1,b=2,c=3) # 结果为:{'a': 1, 'b': 2, 'c': 3}
func(a=1,b=2) # 结果为:{'a': 1, 'b': 2}
# 这时候接收的是一个dict字典

最终可得形参顺序:位置参数  >  *args  >  默认值参数  >  **kwargs,这四种参数可以任意进行使用。

   # 如果想要接收所有的参数可以这样写
# 当你不知道需要需要传递多少参数的时候可这样写,
# 因为这样可以传递任意参数,即无敌
def func(*args,**kwargs):
print(args,kwargs)
func("麻花藤","马云",wtf="胡辣汤")

3,动态参数的聚合与实参的打散

  综上可知,在形参位置上*表示把接收到的位置参数聚合(组合)成一个元组,**表示把接收到的关键字参数聚合(组合)成一个字典,那么在实参位置上给一个字符串,列表,元组或者集合(可迭代对象即可),并在其前面加个*表示把这个序列打散,如果是一个字典,则在其前面加上**。具体示例如下:

def fun(*args):
print(args)
lst = [1,4,7]
# fun(lst[0],lst[1],lst[2])
fun(*lst) # 可以使用*把一个列表按顺序打散
s = "臣妾做不到"
fun(*s) # 字符串也可以打散(可迭代对象即可) def fun(**kwargs):
print(kwargs)
dic = {"a":1,"b":2}
fun(**dic)

4,函数的注释(文档注释)

 def chi(food,drink):
"""
这里是函数的注释,先写一下当前这个函数是干什么的,比如我这个函数就是一个吃
:param food: 参数food是什么意思
:param drink: 参数drink是什么意思
:return: 返回的是什么东东
"""
print(food,drink)
return "very good"

二、命名空间

   def fun():
a =10
print(a)
fun()
print(a) # a不存在了已经

命名空间的分类:

  1,全局命名空间-->我们直接在py文件中,函数外声明的变量都属于全局命名空间;

  2,局部命名空间-->在函数中声明的变量会放在局部命名空间;

  3,内置命名空间 -->存放python解释器为我们提供的名字,如int,str,list这些都是内置命名空间;

加载顺序:

  1,内置命名空间

  2,全局命名空间

  3,局部命名空间(函数被执行的时候)

取值顺序:

  1,局部命名空间

  2,全局命名空间

  3,内置命名空间

 a = 10
def dunc():
a = 20
print(a)
dunc() #结果为:20

作用域:作用域就是作用范围,按照生效范围来看分为全局作用域和局部作用域。

全局作用域:包含内置命名空间和全局命名空间,在整个文件的任何位置都可以使用(遵循从上到下逐行执行);

局部作用域:在函数内部可以使用;

我们可以通过globals()函数来查看全局作用域中的内容,也可以通过locals()来查看局部作用域中的变量和函数信息,具体示例如下:

a = 10
def func():
a = 40
b = 20
def abc():
print("哈哈")
print(a,b) # 这里使用的是局部作用域
print(globals()) #打印全局作用域中的内容
print(locals()) #打印局部作用域中的内容
func()

三,函数的嵌套

1,只要遇见了( )就是函数的调用,如果没有( )就不是函数的调用。

2,函数的执行顺序,具体示例如下:

#函数的嵌套
def fun2():
print(222)
def fun3():
print(666)
print(444)
fun3()
print(888)
print(33)
fun2()
print(555)
# 结果为:
# 33
# 222
# 444
# 666
# 888
#

四、关键字global和nonlocal

现在我们写这样一个代码,首先在全局声明一个变量,然后在局部调用这个变量,并改变这个变量的值,具体如下:

 a = 10
def func():
global a # 这里用的a是全局的
a = 20
print(a)
func()
print(a) # 结果为:20 20 def func():
global a #加global 表示不在局部创建这个变量,而是直接使用全局的a
# 若不存在全局变量a,则创建一个全局变量a
a = 28
print(a)
func()
print(a) # 结果为:28 28

global:

  1,声明一个全局变量;

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

def func():
global a
a = 3
func()
print(a) # 结果为:3 count = 1
def search():
global count
count = 2
search()
print(count) # 结果为:2

注意:对可变数据类型(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,在局部作用域中,对父级作用域(或者更外层作用域且非全局作用域)的变量进行引用和修改,并且引用的哪层,从那层及以下此变量全部发生改变。具体示例如下:

 a = 10
def func1():
a = 20
def func2():
nonlocal a
a = 30
print(a)
func2()
print(a)
func1()
# 结果:
# 加了nonlocal
#
#
# 不加nonlocal
#
#

练习,如果嵌套了很多层,会是一种什么效果,分析明白,那么作用域,global ,nonlocal 就没问题了:

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)
# 结果:
#
#
#
#
#
#
												

最新文章

  1. SSH框架的简单上传功能的实现
  2. dubbox rest服务
  3. 窥探Swift之数组安全索引与数组切片
  4. ui-router中的锚点问题(angular中的锚点问题)
  5. 怎样在myEclipse中使用debug调试程序?
  6. Python开发入门与实战11-单元测试
  7. python-->基础-->002-->input & raw_input
  8. XP系统电脑带安卓手机上网教程(无需adhoc补丁)
  9. lintcode :implement queue by two stacks 用栈实现队列
  10. IOS GCD 使用(一) 简介
  11. HDOJ(HDU) 1587 Flowers(水、、)
  12. tcpdump详细用法
  13. sgu 286. Ancient decoration(最小环覆盖)
  14. Air Raid
  15. 201421123042 《Java程序设计》第12周
  16. .NET、PHP、MySql、JS中的时间戳你每次是手写还是复制?这篇文章让你一次性搞懂
  17. 【ASP.NET】Validation 服务器控件
  18. 吴恩达Machine Learning 第一周课堂笔记
  19. 线程同步-SpinWait
  20. DevExpress WinForms v18.2新版亮点(六)

热门文章

  1. Bestcoder round 18---A题(素数筛+素数打表+找三个素数其和==n)
  2. Codeforces Round #222 (Div. 1) Maze —— dfs(连通块)
  3. 将DotNetBar添加到工具箱中
  4. 蓝桥杯 2014本科C++ B组 李白打酒 三种实现方法 枚举/递归
  5. css animation 简写和参数
  6. 【旧文章搬运】关于在指定进程调用KeUserModeCallback的问题
  7. Nhibernate中多Or条件的查询,很多Or的查询
  8. ubuntu 安装配置 JDK7和Android Studio(apt-get方式)
  9. tomcat+mysql+javaweb+docker
  10. python 之元类