函数基础 函数的作用: 1.定义函数 4.函数的参数 6.函数的名称空间和作用域 7.函数的嵌套 8.函数对象与闭包

1.减少重复代码
2.使程序可以扩展
3.使程序变得易维护

1.定义函数

定义空函数
定义无参函数
定义有参函数

python中函数定义方法:
def test(x):
    "The function definitions"
    x+=1
    return x

def:定义函数的关键字
test:函数名
():内可定义形参
"":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
x+=1:泛指代码块或程序处理逻辑
return:定义返回值

# **2.调用函数**
def bar(x,y):
    z = x + y
    return z
    
res = bar(1,2)    # 有参函数调用
res = bar(1,2)*10    # 函数调用为表达式形式
res = bar(bar(1,2),3)    # 函数调用为另一个函数的参数

# **3.函数的返回值**

返回值数=0:返回None
返回值数=1:返回object
返回值数>1:返回tuple

4.函数的参数

def calc(x,y):  # 形参
    res = x**y
    return res
c = calc(a,b)   # 实参
print(c)

##**形参** **形参**变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,**形参只在函数内部有效**。函数调用结束返回主调用函数后则不能再使用该形参变量
**位置参数和默认参数:**
必须传值的参数是位置参数
默认参数,把常用的参数定义时赋值。
**位置参数必须放在默认参数的前面**

##**实参**
**实参**可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值
**实参传值**
1.按照位置传值
`res = function(1,2)` 2.按照关键字传值
`res = function(x=1,y=2)` 3.混合使用
`res = function(1,y=2)` **混合使用时,位置传值必须在关键字传值的前面
一个形参只能赋值一次**
#**5.*arg和**kwargs** **按位置传值时,多余的值会给*进行处理,存成元祖** **按关键字传值时,多余的值会给**处理** ``` def foo(*args): print(args) foo(1, 2, 3, 4, 5, 6, 7, 8, 9) # 函数返回(1, 2, 3, 4, 5, 6, 7, 8, 9) ```
# 位置传值求和
def my_sum(*nums):
    res = 0
    for i in nums:
        res += i
    return res
z = my_sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print(z) # z = 55

传递*args和**kwargs时

def foo(*args, **kwargs):
    print(args)
    print(kwargs)
foo(1, 2, 3, a=1, b=2, c=3)
# 返回值
# (1, 2, 3)
# {'b': 2, 'a': 1, 'c': 3}

6.函数的名称空间和作用域

内置名称空间
全局名称空间
局部名称空间<br
找变量名或者函数名时,先到局部名称空间中寻找,再到全局名称空间中寻找,最后到内置名称空间中找。

注意:全局的局部名称空间就是全局名称空间

def func():
    y = 1
    print("全局:",globals())  #  全局: {'func': <func at 0x00E856F0>,'x': 1}
    print("局部:",locals())   # 局部:{'y': 1}
x = 1
func()
a = globals() # 此时a 和 b 相等,全局的局部就是全局
b = locals()  

在全局中查看局部和全局名称空间一样

7.函数的嵌套

嵌套调用

# 函数的嵌套调用
def my_max(x,y):
    res = x if x > y else y
    return res


def my_max4(a, b, c, d):
    res1 = my_max(a, b)
    res2 = my_max(res1, c)
    res3 = my_max(res2, d)
    return res3

a = my_max(10,1)
print(a)
print(my_max4(23, 123, 43, 12))

嵌套定义

# 嵌套定义
x = 0
def f1(x):
    print("--->f1",x)
    def f2():
        print("-->f2", x)
        def f3():
            print("->f3",x)
        f3()
    f2()

f1(5) # 执行函数f1,依次执行f2,f3,嵌套时也必须遵守先定义后使用

8.函数对象与闭包

函数的闭包
函数嵌套定义中,内部函数的代码包含对外部作用域的引用,且不是对全局作用域的引用,就叫函数的闭包。

# 函数的闭包
x = 1111
def f1(x):
    y = 1
    z = 3
    def f2():
        print(x, y, z)
    return f2
f = f1(333)
x = 1234
f()
print(f.__closure__) #查看函数是否有闭包,None没有闭包,打印内存地址则存在闭包
print(f.__closure__[0].cell_contents) 
print(f.__closure__[2].cell_contents)

# 333 1 3
# (<cell at 0x01105BF0: int object at 0x010F6EC0>, <cell at   #0x011BC550: int object at 0x1D535910>, <cell at 0x011BC570: int # object at 0x1D535930>)
# 333
# 3




把函数当对象使用

函数名存放的是函数的内存地址,可以把函数名存在字典或列表中,直接加()调用。

# 函数当作对象来使用
def search():
    print("----search----")


def add():
    print("----add----")


def modify():
    print("----modify----")
    

def delete():
    print("----delete----")
    

def menu():
    msg="""
    search
    add
    modify
    delete
    """
    print(msg)


cmd_dict = {
    "search": search,
    "add": add,
    "modify": modify,
    "delete": delete
}
while True:
    menu()
    choice = input("请输入操作的内容")
    cmd_dict[choice]()      # 执行函数