函数初识

定义:

  将一些代码进行封装,减少重复代码

基本结构:

  def 函数名+():

    函数体

  函数名+()    调用:函数名+小括号

执行流程:

  1,先定义,不会执行
  2,调用,会执行定义好的语句
  3..定义好的语句

返回值: return

  1,不写return返回的是None,写了return不写值返回的还是None

def make():
    pass
    return
make()

  2,return就是将内容返回给了调用者,多个返回值是元祖,返回的内容不受限制

  3,函数中当执行到return的时候就结束了,return以下代码都不执行,并终止这个函数

def func():
    print('今天周一')
    print('明天周三')
    return          ps:print('后天周四')不执行
     print('后天周四')
print(func())

静态参数

  形参,定义函数时在上面的就是形参

  实参,下面调用的参数是实参,形参和实参的数量要一一对应

  传参,从实参到形参的过程

  在正常情况下,实参中添加一个元素,形参也要对应的添加一个元素

位置参数:

def func(addr,age):    位置参数,按照位置向上赋值
  print(f'我站在{addr}的操场,静静地看着{age}的你')
  print(f'你站在{addr}的江边,看着来往的{age}的人')
func(
'学校',21)
func(
'黄浦江',21)           ps:实参和形参要上下一一对应

默认参数(关键字参数):

def func(em,msg):        形参中称作默认参数,实参中称作关键字参数
    print(f'小明的目标是{msg},并体验{em}')
func(em='长空栈道',msg='华山')

混合参数:

def func(name,age,level,sex=''):
    print(f'我叫{name},年龄{age},学历{level},性别{sex}')
func('小明',18,'硕士')
  ps:性别为默认参数

参数的使用规则: 

形参:位置参数>默认参数  
实参:位置参数>关键字参数  
混合参数:带等号的参数要放在最后

动态参数:

位置参数的万能传参:

   *args(一个规范),对数据进行封装打包,能接收所有的位置参数;*,代表聚合打包,形参中如果用到动态参数,位置参数>动态位置参数

def eat(*args):      
    print(args)         
eat('包子','饺子','馒头','米饭')
输出结果为:('包子','饺子','馒头','米饭')是元祖类型

实例:

def eat(a,b,*args):                ps:当a,b写在*args之前,会被正常赋值
  print(a,b,args)        
eat('包子','饺子','豆浆','油条')    
输出结果为:包子,饺子,('豆浆','油条')

def eat(*args,a,b):                ps:如果a,b写在*args之后,数据都会被args接收
  print(a,b,args)         
eat('包子','饺子','豆浆','油条')    
输出结果为:('包子','饺子','豆浆','油条')
现在尝试过聚合打包了,那肯定也是可以打散的
def eat(a,b,*args)
    print(a,b,*args)         ps:print中加*,打包的元素会被打散,就会打印出下面的结果  
eat('包子','饺子','豆浆','油条')
输出结果为:包子,饺子,豆浆,油条
再来一个实例:
lst = [12,3,4,16]
def func(*args):        
    print(*args)    args加星,输出结果为:   12,3,4,16
func(*lst) 

lst = [12,3,4,16]
def func(*args):        
    print(args)    args不加星,输出结果为:(12,3,4,16) 
func(*lst)

默认参数的万能传参

  **kwargs,接收的所有的关键字参数,形参中如果用到动态默认参数,默认参数>动态默认参数

例1:
def eat(**kwargs):    接收所有的关键字参数
    print(kwargs)
eat(a=12,b=13,c=16)   输出结果为:{'a':12,'b':13,'c':16}
例2:
def eat(a,b,**kwargs):        两颗星聚合打包,得到的是一个字典    
    print(a,b,kwargs)
eat(a=12,c=16,b=13,d=18)    
              输出结果为:12,13,{'c':16,'d':18}

默认参数的打散

 例3:

def eat(a,b=2,**kwargs):
    print(a,b,*kwargs)             *,一颗星打散,获取的是字典的键;**不能打散
eat(a=12,c=16,b=13,d=18)    
              输出结果为:12,13,c,d(b的值被改变)
例4-1:
dic = {"1":22,"2":55}
def func(**kwargs):
    print(kwargs)             kwargs,得到字典;
func(**dic)               # *dic,会报错     两颗*,打散的效果为:{"1":22,"2",55}
例4-2:
dic = {"1":22,"2":55}
def func(**kwargs):
    print(*kwargs)      *kwargs,获取的是字典的键
func(**dic)             输出内容为:1,2(字典的键)
例4-3:
dic = {"1":22,"2":55}
def func(**kwargs):
    print(kwargs.values())
func(**dic)                      输出结果为:dict_values([22, 55])

形参遵循的规则:

  位置参数>动态位置参数>默认参数>动态默认参数def func(*args,**kwargs)

函数注释

def func(*args,**kwargs):   注释时,要加上函数一起注释,不然未出现缩进错误
''' 
:param args:   万能的位置参数
:param kwargs: 万能的默认参数
:return : 返回值
'''

print(args)
print(kwargs)
return args
print(func.__doc__)        查看函数的注释

名称空间

  内置空间,全局空间,局部空间(局部空间的变量不能共享)

加载顺序

  内置空间>全局空间>局部空间

取值顺序:

  局部空间>全局空间>内置空间

python中的关键字存储在内置空间,py文件中顶头写的内容就存在全局空间,函数内写的变量是存在局部空间

def func():
    a = 1            局部空间
    print(a)
func()
此时,a就是存在局部空间的变量
a = 10
def func():
    print(a)          局部空间没有,到全局找
func()    

  而在这个函数中,a是一个全局变量,当print(a)时,局部空间没有变量a,就到全局找

命名空间

  内置+全局构成一个空间,      通过globals(),来查看全局作用域的内容

  局部空间             通过locals()来查看局部作用域的内容

函数嵌套

  在嵌套函数中,要一层一层的往下找,同级别的也要遵守从上到下的顺序.那接下来就通过一些实例来说明函数的嵌套,更好地了解函数的执行流程

1    def func(): 
4        func1()
6        print(1)
2    def func1():
5        print(2)
3    func            输出结果为: 2,1      ps:最左侧数字为函数的执行流程 
示例5.1,简单嵌套
要注意的是,函数执行完还有一个回退的过程
1    def func():
7        func1()
9        print(1)
2    def func2():
5        print(33)
6        func()
3    def func1():
8        print(2)
4    func2()            输出结果为:33,2,1      左侧数字是函数嵌套的执行流程
示例5.2
在这个嵌套中,函数的执行流程还是比较容易梳理出来的
1   def func():
3       print(1)
4       def func1():
7           print(2)
8           func3()
5       def func3():
9           print(4)          
6         func1()
2   func()                      按照这样的流程,输出结果为:1,2,4


def func():
    print(1)
    def func1():
        print(2)
        func3()
        def func2():    但在这里添加一个func2时,它是func1局部空间里的一个数据,是不能共享的
            print(4)
           def func3():
               print(4)
        func2()               在调用func2时,先到func3里找,找不到会报错    
    func1()
func()
示例5.3
要注意:局部空间的变量不能共享
def func1():                
    print(1)                
    def func2():                
        print(2)            
        def func3():            
            print(3)            
        def func6():            
            print(6)
            func3()              
            def func4():            
                print(4)        
                def func7():        
                    print(7)        
                func7()            
                def func5():        
                    print(5)        
                func5()            
            func4()                
        func6()                
    func2()                    
func1()                            输出结果为:1,2,6,3,4,7,5
示例5.4

global修改全局变量

a = 10 
def func():
    global a            #  申明要修改全局变量a的值,如果全局没有
     a = 20 
     print(a)
func()
print(a)          输出结果为20,20
示例6.1
a = 10
def func():
    global b        
    b = 100
     print(a)
    print(locals())        # {},空字典是存放局部作用域里的一个容器
func()
print(b)            输出结果为:10,100
示例6.2

nonlocal修改局部变量

n = 1
def func():
    n = 10
    def func1():
        print(n)
    func1()
func()
print(n)     输出结果为:10,1(10是局部的func1里没有,寻找的是func里的n=10;1是最后的print打印的全局变量)
正常情况
n = 1
def func():
    n = 10
    def func1():
        nonlocal n           修改离得最近上一层的变量值,如果没有,继续往上找
        n = 100              直到局部变量的最外层
        print(n)
    func1()
func()
print(n)               输出结果为:100,1
nonlocal修改局部变量

 
posted @ 2019-01-12 14:06  DF-包子  阅读(321)  评论(0编辑  收藏  举报