7.10函数(二)

函数

命名关键字参数

(1)在函数定义阶段 写在 * 与 ** 可变长参数之间的形参

(2)在给命名关键字参数传值的时候,只能用关键字为其传值

def func(x,y=1,*args,z=3,m,**kwargs):
    print(x,y)
    print(args)
    print(z,m)
    print(kwargs)
func(1,2,1,2,3,4,5,6,7,8,9,0,z=69,m=999,o=666999,l = 999666)

(3)在定义阶段,给你感觉好像是z是默认值参数,放在了m这个位置参数的前面了,应该报错

(4)但其实z和m都是命名关键字参数,不是默认值参数和位置参数,所以不会报错

函数对象

函数是第一类对象,函数名指向的值可以被当作参数传递

1.函数名可以被传递

def func():
    print('from func')
func()
print(func)
f = func
f()  # 其实指向的也是函数func指向函数体代码的内存地址
print(f)
print(id(func))
print(id(f))

2.函数名可以被当做参数传递给其他函数

def func():
    print('from func')

def index(args):
    print(args)
    args()  # 运行func()函数
    print('from index')
index(func)

3.函数名可以被当做函数的返回值

def index():
    print('from index')

def func():
    print('from func')
    return index
res = func()  # res = index
print(res)
res()  # 就是index()

4.函数名可以被当做容器类型的参数

def func():
    print('from func')
print(func())  # 返回值为None
l = [1,2,func,func()]  # [1,2,<function func at 0x000001F7D79899D8>,None]
print(l)

5.应用

循环打印项目功能提示信息,供用户选择,用户选择谁就执行谁

def register():
    username = input('username>>>:').strip()
    pwd = input('password>>>:').strip()
    print(username,pwd)
    print('register ...')
def login():
    print('login ...')
def transfer():
    print('transfer ...')
def shopping():
    print('shopping...')
def pay():
    print('pay ...')
msg = """
1 注册
2 登陆
3 转账
4 购物
5 支付
"""
func_dict = {
    '1':register,
    '2':login,
    '3':transfer,
    '4':shopping,
    '5':pay,
}
while True:
    print(msg)
    choice = input('请现在你想要执行的功能>>>:').strip()
    if choice in func_dict:
        func_dict.get(choice)()  # 函数名()  就是调用函数
    else:
        print('你输入的功能暂时没有')
View Code

函数的嵌套使用

在函数内部调用其他函数,可以将复杂的逻辑简单化

def index():
    print('from index')

def func():
    index()  # 调用函数index()
    print('from func')
func()

用法举例:比较大小,取最大值

def my_max(x,y):
    if x > y:
        return x
    return y

def my_max4(a,b,c,d):
    res1 = my_max(a,b)
    res2 = my_max(res1,c)
    res3 = my_max(res2,d)  # 依次比较大小
    return res3
print(my_max4(1,2,10,3))

函数的嵌套定义

def outer():
    print('from outer')
    def inner():
        print('from inner')
    return inner
res = outer()  # 返回值inner
res()  # 就是inner()

应用场景

写一个函数,该函数用户可以通过传参的不同控制函数执行不同的功能

def choice(type):
    def login():
        print('login ...')
    def transfer():
        print('transfer ...')
    def shopping():
        print('shopping...')
    def pay():
        print('pay ...')
    if type == 1:
        login()
    elif type == 2:
        transfer()
    elif type == 3:
        shopping()
    elif type == 4:
        pay()
choice(4)
View Code

名称空间

1.名称空间是什么?

就是放名字的地方,存放的是变量名与变量值的内存地址的绑定关系的地方,要想访问一个变量的值,必须先去名称空间中拿到对应的名字,才能够访问变量的值

name = 'francis'
print(name)

2.名称空间的分类

(1)内置名称空间:python解释器提前给你定义好的名字(已经存放到内置名称空间中了)

比如:len、print、max、min

(2)全局名称空间:文件级别的代码

x = 1

if 1 == 1:
    y = 2
print(y)

for z in [1,2,3]:
    print(z)

while True:
    a = 3
# x,y,z,a都会放到全局名称空间

if for while 无论嵌套多少层,它们内部所创建的名字都是全局名称空间的

(3)局部名称空间:函数体内创建的名字都属于局部名称空间

def func():
    x = '12345'  # x属于局部内存空间
print(x)

3.生命周期(存在时间)

(1)内置名称空间:只要python解释器一启动立马创建,关闭python解释器的时候内置名称空间自动销毁

(2)全局名称空间:只要你右键运行py文件会自动创建,py文件程序运行结束自动销毁 

(3)局部名称空间:函数被调用的时候自动创建,函数执行结束立即销毁(动态创建动态销毁)

名称空间的查找顺序

print(len)  # 全局之前未定义len,就去内置中找
len = '我是全局名称空间的len'
def func():
    len = '我是局部名称空间的len'
    print(len)
func()  # 站在局部名称空间的位置查找len
print(len)  # 站在全局名称空间的位置查找len

1.查找顺序:

  需要先确定你当前在哪(大前提)

  1.站在局部: 局部 >>> 全局 >>> 内置

  2.站在全局: 全局 >>> 内置

2.重点:

函数在定义阶段查找名字的顺序就已经固定了,不会因为函数的调用位置变化而改变

作用域

1.全局作用域

全局有效:内置名称空间、全局名称空间

2.局部作用域

局部有效:局部名称空间

3.在局部修改全局的不可变数据类型

global:局部修改全局,如果想修改多个用逗号隔开

x = 1  # 不可变类型
name = 'francis'
def func():
    global x,name  # 修改全局变量 而不是创建局部名称空间
    x = 999
    name = 'jason'
func()
print(x)
print(name)

4.在局部修改局部的

nonlocal:局部修局部,如果想修改多个用逗号隔开

def func():
    x = 1
    def index():
        nonlocal x  # 修改局部变量
        x = 999
    index()
    print(x)
func()
原文地址:https://www.cnblogs.com/francis1/p/11165227.html