函数的初始及进阶

函数初始

函数的定义与调用

'''
def 函数名 (参数):
    函数体
    
函数名:设定与变量相同
执行函数: 函数名()
'''

 

函数的返回值

# 函数返回值 return
'''
    1、遇到return,结束函数
    2、给函数的调用者(执行者)返回值
        无return返回None
        return不写 或者None返回 None
        return返回单个数
        return返回多个值,将多个值放在元组中返回
'''

 

函数的参数

'''
从实参角度
    1 位置参数     必须--对应,按照顺序
    2 关键字参数   必须--对应,不分顺序
    3 混合参数     --对应,关键字参数必须在位置参数的后面
形参角度
    1 位置参数 和实参的位置参数一致
    2 默认参数 默认参数必须在位置参数后面
    3 动态参数 万能参数 *args **kwargs,适用于传参个数不固定
        *args 接收所有的位置参数
        **kwargs 接收所有的关键字参数

    形参最终的摆放顺序: 位置参数,*args, 默认参数, **kwargs
'''
#三元运算
#ret = a if a > b else b
# def compare(a, b):
#     if a > b:
#         return a
#     else:
#         return b
# print(compare(1, 2))

 

# 需求把l1 和 l2 列表中的每个传输传递到args中
def func1(*args, **kwargs):
    print(args)
    print(kwargs)

l1 = [1,2,3,4]
l2 = [5,6,7,8]
# 需求把l1 和 l2 列表中的每个传输传递到args中
func1(*l1, *l2)

 

dic1 = {'name1' : 'alex'}
dic2 = {'name2' : 'eric'}
#需求把dic1和dic2中的每一个键值对传入kwargs
# 实现需求的方法
func1(**dic1, **dic2)

 

函数的进阶

命名空间和作用域

命名空间一共分为三种:

  全局命名空间

  局部命名空间

  内置命名空间

 

名称空间: 全局名称空间 局部名称空间 内置名称空间
名称空间,命名空间: 变量与值的内存地址的关系

临时名称空间:局部名称空间,只要函数一致性,会临时开辟一块内存空间,存入函数里面的函数与值的关系,随着函数的执行结束,临时名称空间消失

作用域:
    全局作用域: 全局名称空间, 内置名称空间
    局部作用域: 局部名称空间

加载顺序: 内置名称空间--》全局名称空间--》局部名称空间(函数执行时)
取值顺序: 局部名称空间--》全局名称空间--》内置名称空间(从内到外的)

 

global关键字,nonlocal关键字

global:

  1,声明一个全局变量。

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

#函数可以引用全局变量,但是不能改变

# global 1、声明一个全局变量
# def func1():
#     global name
#     name = 'alex'
#     return
# func1() #必须执行下函数,才会声明为全局变量
# print(name)

 

nonlocal:

  1,不能修改全局变量。

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

#nonlocal 只能操作一个非全局变量,对局部作用域的函数进行引用及修改
'''
name1 = 'alex'
def func1():
    nonlocal  name1
    name1 = 'wusir'
    return
func1()
print(name1)

SyntaxError: no binding for nonlocal 'name1' found
# def func1():
#     name = 'alex'
#     print(name)
#     def inner():
#         nonlocal name
#         name = 'wusir'
#         print(name)
#     inner()
#     print(name)
# func1()

 

关键字

# globals locals
# 打印函数内所有的局部变量 和全局变量
def fun1():
    print(globals())
    print(locals())
    # count += 1
    print(count)
fun1()

return --》{'__name__': '__main__', '__doc__': '\n名称空间: 全局名称空间 局部名称空间 内置名称空间\n名称空间,命名空间: 变量与值的内存地址的关系\n\n临时名称空间:局部名称空间,只要函数一致性,会临时开辟一块内存空间,存入函数里面的函数与值的关系,随着函数的执行结束,临时名称空间消失\n\n作用域:\n    全局作用域: 全局名称空间, 内置名称空间\n    局部作用域: 局部名称空间\n\n加载顺序: 内置名称空间--》全局名称空间--》局部名称空间(函数执行时)\n取值顺序: 局部名称空间--》全局名称空间--》内置名称空间(从内到外的)\n\n闭包\n内层函数对外层函数非全局变量的引用\n闭包的好处:如果python监测到闭包,他有一个机制,你的局部作用域不会随着函数结束而结束\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000002149278>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/pycharm/untitled/自动化运维21期/day3/03函数的进阶.py', '__cached__': None, 'count': 1, 'fun1': <function fun1 at 0x00000000020A1F28>}
{}
1

 

函数名的本质

'''
函数名
1、函数名相当于变量,可以互相赋值
def func1()
    pass
f1 = func1

2、函数名可以当做函数的参数
def func1():
    print(666)
def func2(argv):
    print(777)
    argv()
func2(func1)

output:
777
666

3、可以当成容器类数据类型的参数
# 需求是100个函数,依次执行
def func1():
    print(666)
def func2():
    print(777)
def func3():
    print(888)

l1 = [func1, func2, func3]
for n in l1:
    n()
    
4、函数名可以当做函数的返回值
def func1():
    print(666)
def func2(argv):
    print(777)
    return argv
ret = func2(func1)
ret()

output:
777
666
'''

 

闭包

内层函数对外层函数非全局变量的引用
闭包的好处:如果python监测到闭包,他有一个机制,你的局部作用域不会随着函数结束而结束

非闭包的demo
name = 'alex'
def func1():
    def inner():
        print(name)
    print(inner.__closure__)
func1()

return --》 None

闭包demo
def wrapper():
    name = 'alex'
    def inner():
        print(name)
    print(inner.__closure__)
wrapper()

return --> (<cell at 0x00000000026A55B8: str object at 0x00000000027270D8>,)

def wrapper(argv):
    def inner():
        print(argv)
    print(inner.__closure__)

wrapper('alex')(<cell at 0x00000000021455B8: str object at 0x00000000026F7298>,)

return --> 

 

posted @ 2018-04-18 15:18  Pyter  阅读(235)  评论(0编辑  收藏  举报