day10

 哪个更痛苦,努力还是后悔?

前方高能---函数的进阶

1.函数参数--动态传参

2.名称空间,局部名称空间,全局名称空间,作用域,加载顺序

3.函数的嵌套

4.gloabal,nonlocal关键字

 

一. 函数参数--动态传参

  形参的第三种: 动态参数

1. 动态接收位置参数

  动态接收参数的时候要注意: 动态参数必须在位置参数后面.

def  chi(*food, a, b):
       print('我要吃,',food,a,b)
chi('大米饭','小米饭',a='黄瓜',b='茄子')    # 必须用关键字参数来指定.

   先写位置函数,然后再用动态函数.

def chi(a,b,*food):
      print('我要吃',a,b,food)
chi('大米饭','小米饭','啦啦啦','面条')  # 前两个参数用位置参数来接收,后面的参数用动态参数接收

  顺序: 位置参数,动态参数*,默认值参数.

2. 动态接收关键字参数

在python中可以动态的位置参数,但是'这种情况只能接收位置参数无法接收关键字参数'

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

def func(**kwagrs):
      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)

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

  最后顺序(*):

    位置参数,*args,默认值参数,**kwargs

# 如果想接收所有的参数
def func(*args,**kwargs):
      print(agrs,kwargs)
func('麻花藤','马芸',wtf='胡辣汤')

  动态参数的另一种传参方式:

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)

    函数的注释:

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解释器为我们提供的名字,list,tuple,str,int这些都是内置命名空间.

  加载顺序:

  1, 内置命名空间

  2,全局命名空间

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

  取值顺序:

  1,局部命名空间

  2,全局命名空间

  3,内置命名空间

a = 10
def func():
      a = 20
      print(a)
func()     # 20

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

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

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

作用域命名空间:

  1,全局作用域 : 全局命名空间 + 内置命名空间

  2, 局部作用域: 局部命名空间

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

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

 三. 函数的嵌套

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

2. 函数的执行顺序

def fun1():
      print(111)
def fun2():
      print(222)
      fun1()
fun2()
print(111)

# 函数的嵌套
def fun2():
      print(222)
      def fun3():
            print(666)
      print(444)
      fun3()
      print(888)
print(333)
fun2()
print(555)

 四. 关键字global和nonlocal

  首先我们写这样一个代码,首先在全局声明一个变量,然后再局部调用这个变量,并改变这个变量的值.

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

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

lst = ['哈哈','请问','旺旺']
def func():
     lst.append('哎哎啊')    # 对于可变数据类型可以直接进行访问,但是不能改地地址,说白了,不能赋值.
     print(lst)
func()
print(lst)

nonlocal 表示在局部作用域中,调用父级命名空间中的变量.

a = 10
def func1():
      a = 20
      def func2():
            nonlocal a 
            a = 30
            print(a)
       func2()
       print(a)
func1()

 

posted @ 2018-08-09 17:16  吧啦吧啦吧啦  阅读(82)  评论(0编辑  收藏  举报