Python学习-第五章

5.1 之前的基础知识不记录了

5.2 之前的基础知识不记录了

5.2.1 关键字参数

假设一个函数:

def createUser(name,age):
    print(“姓名:”+name+”,年龄:”+age)

关键字参数:
按照参数名传入参数,例如:

createUser(name=“liuan”,age=30)

位置参数:
对照形参位置传入的参数,例如:

createUser(“liuan”,30)

如果需要混合使用关键字参数和位置参数,则须遵守:
必须将位置参数放在关键字参数前

5.2.2 参数默认值

示例:

def say_hi(name="liuan",message="hello world!"):
    pass

Python规定,带默认值的参数放在形参列表最后

5.2.3 参数收集(个数可变的参数)

books此时可传入多个参数,并被处理为元祖传入
示例:

    def test(a,*books):
        print(books)

Python还可以收集关键字参数,会将关键字参数收集成字典。为了让Python能收集关键字参数,需要在参数前面添加两个星号。
示例:

    def test(x,y,z,*books,**scores):
        print(scores)
    test(1,1,1,"xxx","yyy","zzz",xxx=222,yyy=333,zzz=444)

{'xxx':222,'yyy':333,'zzz':444}

5.2.4 逆向参数收集

在程序已有列表,元祖,字典等对象的情况下,把它们的元素拆开传给函数的参数
示例:

def test(name,*nums):
    print("name参数:"+name)
    print("nums参数:"+str(nums))
myTuple=(1,2,3,4)
test("liuan",*myTuple)

结果:

name参数:liuan
nums参数:(1, 2, 3, 4)

如果不使用逆向收集(不使用星号),整个元祖都将会作为一个参数,而不是将元祖的元素作为多个参数。
输出结果会是:

name参数:liuan
nums参数:((1, 2, 3, 4),)

也支持字典的逆向收集,字典将会以关键字参数的形式传入给函数的参数。

def bar(book,price,desc):
    print(book,",这本书价格是:",price)
    print('描述信息:',desc)

bar(book="钢铁是怎样炼成的",price=1000,desc="一本励志故事")

运行结果:
钢铁是怎样炼成的 ,这本书价格是: 1000 描述信息: 一本励志故事

dict1={"book":"ddd","price":222,"desc":"dddfeee"}
bar(**dict1)

运行结果:
ddd ,这本书价格是: 222 描述信息: dddfeee

5.2.5 函数的参数传递机制

  • 所谓的值传递,就是将实际参数值的副本传入函数,而参数本身不会受到影响。
  • 但是如果将参数包装成list,dict传入函数,则可以改变参数,因为函数复制的是指向集合的引用对象(指针)。

结论:

  1. 不管什么类型的参数,在Python函数中对参数直接使用“=”符号赋值是没用的,并不能改变参数。
  2. 如果需要让函数修改某些数据,则可以通过将这些数据包装成列表、字典等可变对象,然后将这些可变对象传入函数,在函数中通过列表、字典的方法修改它们,才能改变这些数据。

5.2.6 变量作用域

  • 局部变量:
    在函数中定义的变量,每个函数执行时,局部变量存在临时分配的栈内存中,运行结束,内存释放,局部变量销毁。
  • 全局变量:
    在函数外面,全局范围内定义的变量。可以在所有函数中被访问。

Python提供了3种工具函数来获取指定范围内的“变量字典”

  1. globals():返回全局范围内所有的全局变量的字典,可以通过globals[‘key’]来获取字典中key关键字对用的数据
  2. locals():返回当前局部范围内所有变量组成的变量字典,可以通过locals[‘key’]来获取字典中key关键字对用的数据
  3. vars(object):获取指定对象范围内所有变量组成的变量字典,如果不传入object参数,则作用与local()一致

示例:

name="liuan"
def test():
    print(name)
    name="xiayin"
test()
print(name)

报错:
UnboundLocalError: local variable 'name' referenced before assignment

原因:
Python语法规定:在函数内部对不存在的变量赋值时,默认为重新定义新的局部变量,会覆盖全局同名变量,所以上面程序报错。

以上代码若想无错运行,可作如下修改:

name="liuan"
def test():
    print(globals('name'))
    name="xiayin"
test()
print(name)

运行结果:
liuan liuan

name="liuan"
def test():
    global name
    print(name)
    name="xiayin"
test()
print(name)

运行结果:
liuan xiayin

以上两种修改方案,结果不同。

5.3 局部函数

Python支持在全局函数内部定义局部函数:

def getMathFunc(type,nn):
    def square(n):
        return n * n
    def cube(n):
        return n * n * n
    def factorial(n):
        result=1
        for index in range(2,n+1):
            result *= index
        return result
    
    if type == 'square':
        return square(nn)
    elif type=='cube':
        return cube(nn)
    else:
        return factorial(nn)

print(getMathFunc('square',3))
dict1={"type":"cube","nn":5}
print(getMathFunc(**dict1))
print(getMathFunc('factorial',9))

在函数中定义的局部函数中会出现一种情况,局部函数内的变量会遮蔽它所在的函数内的局部变量:

def foo():
    name="liuan"
    def bar():
        print(name)
        # 遮蔽了所在函数中的局部变量name
        name="xiayin"
    bar()
foo()

可改为:

def foo():
    name="liuan"
    def bar():
        # 访问bar()所在函数内的局部变量name,而非bar()的局部变量name
        nonlocal name
        print(name)
        # 遮蔽了所在函数中的局部变量name
        name="xiayin"
    bar()
foo()

提示:
nonlocal()和global()功能大致相似,区别为:

  • global()用于声明访问全局变量
  • nonlocal()用于声明访问当前函数所在函数内的局部变量

5.4 函数的高级内容

5.4.1 使用函数变量

def pow(base,exponent):
    result=1
    for i in range(1,exponent+1):
        result *=base
    return result
# 将函数pow赋值给变量my_fun
my_fun=pow
print(my_fun(3,4))

def area(width,height):
    return width * height
# 将函数area赋值给变量my_fun
my_fun=area
print(my_fun(3,4))

以上示例代码说明,当函数赋值给变量后,也可通过该变量来调用函数。

5.4.2 使用函数作为函数形参

Python支持像使用其他参数一样使用函数参数

def map(data,fn):
    result=[]
    for e in data:
        result.append(fn(e))
    return result
# 定义平方根函数
def square(n):
    return n * n
# 定义立方根函数
def cube(n):
    return n * n * n
# 定义阶乘函数
def factorial(n):
    result=1
    for i in range(2,n+1):
        result *= i
    return result
data=[3,4,9,5,8]
print('原数据',data)
print('计算数组元素的平方')
print(map(data,square))
print('计算数组元素的立方')
print(map(data,cube))
print('计算数组元素的阶乘')
print(map(data,factorial))

5.4.3 使用函数作为返回值

Python还支持使用函数作为其他函数的返回值

def get_math_func(type):
    # 定义平方根函数
    def square(n):
        return n * n
    # 定义立方根函数
    def cube(n):
        return n * n * n
    # 定义阶乘函数
    def factorial(n):
        result=1
        for i in range(2,n+1):
            result *= i
        return result
    if type == "square":
        return square
    elif type =="cube":
        return cube
    elif type =="factorial":
        return factorial
print(get_math_func("factorial")(5))
print(get_math_func("cube")(100))
print(get_math_func("square")(10000))

5.5 局部函数与lambda表达式

5.5.1 使用lambda表达式代替局部函数

def get_math_func(type):
    # 定义阶乘函数
    def factorial(n):
        result=1
        for i in range(2,n+1):
            result *= i
        return result
    if type == "square":
        return lambda n:n * n
    elif type =="cube":
        return lambda n:n * n * n
    elif type =="factorial":
        return factorial
print(get_math_func("factorial")(5))
print(get_math_func("cube")(100))
print(get_math_func("square")(10000))

lambda表达式公式如下:

lambda [parameter_list] : 表达式

例如:

def add(x,y):
	return x+y

可简化为:

lambda x,y:x+y

虽然lambda表达式只能创建简单的函数对象,但仍有两大优势:

  • 对于单行函数,代码更为简洁
  • 对于不需要多次复用的函数,用完之后立刻释放,提高了性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值