形参:

1.位置传参  2. 默认值传参. 3.动态传参

一   动态传参(形参的一种):

 之前我们说过了了传参, 如果我们需要给⼀一个函数传参, ⽽而参数⼜又是不确定的. 或者我给⼀一个
函数传很多参数, 我的形参就要写很多, 很⿇麻烦, 怎么办呢. 我们可以考虑使⽤用动态参数.

 动态传参分两种:

(1) 动态接收位置参数和默认值参数

def chi(*food):# *表⽰示接收任意内容
print("我要吃", food)
chi("⼤大⽶米饭", "⼩小⽶米饭")
结果:
我要吃 ('⼤大⽶米饭', '⼩小⽶米饭') # 多个参数传递进去. 收到的内容是元组tuple

需要注意的是 : 动态参数必须在位置参数后⾯  例如:

def chi(*food, a, b):
print("我要吃", food, a, b)
chi("⼤大⽶米饭", "⼩小⽶米饭", "⻩黄⽠瓜", "茄⼦子")
这时程序运⾏行行会报错. 因为前⾯面传递进去的所有位置参数都被*food接收了了. a和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("⾹香蕉", "菠萝", "葫芦娃", "口罩") # ⾹香蕉 菠萝 葫芦娃 ('口罩',) 默认值不不⽣生效

 默认值参数写在动态参数前⾯面. 默认值只有一种情况可能会⽣生效

例子:

def chi(a, b, *food, c="娃哈哈"): #在这里. 其实相当于把传进来的参数做了一次聚合, 聚合成一个元组
print(a, b, food, c) 
chi(
"⾹香蕉", "菠萝") # ⾹香蕉 菠萝 () 娃哈哈 默认值⽣生效
chi(
"⾹香蕉", "菠萝", "葫芦娃") # ⾹香蕉 菠萝 ('葫芦娃',) 娃哈哈 默认值⽣生效
chi(
"⾹香蕉", "菠萝", "葫芦娃", "⼝口罩") # ⾹香蕉 菠萝 ('葫芦娃', '⼝口罩') 娃哈哈 默 认值生效

这么写就生效了 这个时候如果不给出关键字传参. 那么你的默
认值是永远都⽣生效的

所以得到结论 :

默认值.位置传参和动态传参的顺序为:位置  动态 默认值参数

(2)关键字传参

在python中使⽤用**来接收动态关键字参数

def func(**kwargs):
print(kwargs)
func(a=1, b=2, c=3)
func(a=1, b=2)
结果:
{'a': 1, 'b': 2, 'c': 3}
{'a': 1, 'b': 2}         这个时候接收的是⼀一个dict

顺序问题

def func(a, b, c, d):
print(a, b, c, d)
# 关键字参数必须在位置参数后⾯面, 否则参数会混乱
func(1, 2, c=3, 4)

所以关键字参数必须在位置参数后⾯面. 由于实参是这个顺序. 所以形参接收的时候也是这
个顺序. 也就是说位置参数必须在关键字参数前⾯面. 动态接收关键字参数也要在后⾯面

综上所述最终结论顺序:

位置参数 > *args > 默认值参数 > **kwargs        这四种参数可以任意的进行使⽤

 

无敌,模式: 

所有的参数都能接收
def func(*args, **kwargs):
#     print(args)
#     print(kwargs)
#
# func(1, 2, 5, jj="陶喆", jay="zhoujielun", soup="胡辣汤") 
 结果为:(1, 2, 5)
{'jj': '陶喆', 'jay': 'zhoujielun', 'soup': '胡辣汤'}

 * 和**出现在实参上时

拿个例子来说

def func(*args):
    print(args)
   
lst = "娃哈哈"
func(*lst)      结果('娃', '哈', '哈')  #  在实参位置 * 表示打散, 打散的是可迭代对象
def func( **kwargs):
    
  print(kwargs)
  dic = {"2": "明教教主", "谢逊": "金毛狮王", "范瑶": "光明右使"}
  ##func(张无忌=dic['张无忌'], 谢逊=dic['谢逊'], 范瑶=dic['范瑶'])
  func(**dic)  结果: {'2': '明教教主', '谢逊': '金毛狮王', '范瑶': '光明右使'} 
  # 这里的** 是把字典打散. 字典的key作为参数的名字, 字典的值作为参数的值传递给形参

 

小结:

       1. *args  位置参数的动态传参. 系统会自动的把所有的位置参数聚合成元组
# 2. **kwargs 关键字的动态传参. 系统会自动把所有的关键字参数聚合成字典
# 3. def func(*args, **kwargs): 无敌传参
# 4. 顺序: 位置参数, *args, 默认值, **kwargs
# 5. 在使用的时候, 可以任意的进行搭配
# 4. 在实参上. *, **表示的打散. 在形参. *,** 表示聚合

二    命名空间

1.名称空间

  内置空间    ::存放python解释器为我们提供的名字, list, tuple, str, int这些都是内置空间

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

  局部空间 :  ;在函数中声明的变量量会放在局部命名空间

加载顺序:

1. 内置命名空间

2. 全局命名空间
3. 局部命名空间(函数被执⾏行行的时候)

最开始会开辟一个自己的命名空间- 内置名称空间

a = 10 # 全局 # def func(): # # a = 20# 局部 # print(a)#局部 # # func()

 

取值顺序:

  局部 => 全局 => 内置

 

  作用域(变量或者函数的声明周期)

作⽤用域就是作⽤用范围, 按照⽣生效范围来看分为 全局作⽤用域和局部作⽤用域
全局作⽤用域: 包含内置命名空间和全局命名空间. 在整个⽂文件的任何位置都可以使⽤用(遵循
从上到下逐⾏行行执⾏行行). 局部作⽤用域: 在函数内部可以使⽤用.

 

全局作用域: 全局名称空间+内置名称空
局部作用域: 局部名称空间
1.我们可以通过globals()函数来查看全局作⽤用域中的内容, 也可以通过locals()来查看局部作
⽤用域中的变量量和函数信息
1. globals() 查看全局作用域中的所有内容
# qiao = "乔峰"
# def 抗收音机():
# bgm = "难念的经"
# print("娃哈哈")
# print(locals())
# 抗收音机() #


  print(globals())  ## 查看全局作用域中的内容

print(locals()) # locals()查看的是当前作用域中的内容

四 函数的嵌套

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

def func1():
#     print("我是func1")
#
# def func2():
#     print("我是func2")
#     func1()
#
# def func3():
#     func2()
#     print("我是func3")
# func3()
# 这样的代码不是嵌套. 互相调用

 

2. 函数的执行顺序

简单的嵌套  例子1

ef outer():
#     def inner():
#         print("我是内部")
#     print("我是外部")
#     inner()
#
# outer()

例子2

ef outer():
#     print("我是外面的")
#     def inner_1():
#         def inner_2():
#             print("我是里面的2")
#         inner_2()
#         print("我是里面的1")
#     inner_1()
#     print("我是外面的收尾")
#
# outer()

3.关键字global和nonlocal

首先在全局声明一个变量, 然后再局部调用这个变量, 并改变这
个变量的值

 

global表示. 不再使用局部作用域中的内容了. 而改用全局作用域中的变量

a = 100
def func():
  global a # 加了了个global表示不再局部创建这个变量了. 而是直接使用全局的a 把全局的变成和局部一样的变量
  a = 28
  print(a)
func()
print(a)      

 a = 10
# def func():
#     global a #表示在当前作用域中的使用的a是全局中的变量
#     a = 20 # 所有的a都是外面的了
#     print(a) # 现在只有看的权利
#

 

例子2

lst = ["麻花藤", "刘嘉玲", "詹姆斯"]
def func(): lst.append(
"⻢马云云") # 对于可变数据类型可以直接进⾏行行访问. 但是不不能改地址. 说⽩白 了了. 不不能赋值 print(lst) func() print(lst)

nonlocal(找的是局部当中, 离他最近的上层的那个变量)

def outer():
#     a = 10
#     def inner():
#         nonlocal a # 找的是局部当中, 离他最近的上层的那个变量
#         a = 20
#         print(a)
#     print(a) # 10
#     inner() # 20
#     print(a) # 20
# outer()
 global 引入全局变量, 可以定义全局变量
nonlocal 引入局部中离他最近的外层变量
def func():
    global a # 没有也得有. 自动帮你创建    # 定义全局变量  
    a = 20

func()
print(a)  

 

posted on 2018-09-14 17:14  隐&  阅读(249)  评论(0编辑  收藏  举报