欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

python函数

时间:2023-08-27
文章目录

一、函数的定义二、4种函数的参数形式三、函数返回值四、函数的作用域,全局/局部变量五、函数的嵌套六、函数的递归七、匿名函数lambda八、匿名函数lambda的应用九、匿名函数和常规函数对比十、函数式编程的特点十一、函数式编程map()、filter()、reduce()函数十二、函数式编程map() VS 列表推导式十二、函数是一等公民十三、函数装饰器十三、带参数的函数装饰器十三、不定长参数的函数装饰器十四、防止被装饰的函数改变十五、函数装饰器的嵌套银行系统综合案例prettytable将二维数组的打印美化成表格 一、函数的定义

# 创建高楼def create_building(): # 创建房间 create_room() # 创建电梯 create_stair()def create_room(): print('开始创建房间') print('正在创建房间') print('创建房间完成')def create_stair(): print('开始创建电梯') print('正在创建电梯') print('创建电梯完成')create_building()

开始创建房间正在创建房间创建房间完成开始创建电梯正在创建电梯创建电梯完成

二、4种函数的参数形式

# 1、普通参数def say_hi(name): print(f'hello,{name}') print('欢迎来到大熊课堂') say_hi('JackMa')def create_window(width,height): print(f'窗口的宽是{width};高是{height}') create_window(2,1)# 2、默认参数def total(hour, salary=8): print(f'今天的薪水是{hour * salary}元') total(8) # 用默认值,不会报错total(8, 10)# 3、关键字参数 解决函数传参顺序问题def student(firstname, lastname): print(f'firstname is {firstname};lastname is {lastname}')student('andy', 'Feng')student(lastname='Feng', firstname='andy')# 4、不定长参数 *args元组 **kwargs字典def my_function(width, height, *args, **kwargs): print(width) print(height) print(args) print(kwargs)my_function(2.3, 4.5, 'hello', 'welcome', 'to', 'daxiong', 'thankyou', lastname='Feng', firstname='andy')

hello,JackMa欢迎来到大熊课堂窗口的宽是2;高是1今天的薪水是64元今天的薪水是80元firstname is andy;lastname is Fengfirstname is andy;lastname is Feng2.34.5('hello', 'welcome', 'to', 'daxiong', 'thankyou'){'lastname': 'Feng', 'firstname': 'andy'}

三、函数返回值

# 例1:求圆的面积pi = 3.14def area(r): return pi * (r ** 2)print(area(2))# 例2:将分钟转化为“时-分” 100分钟=1小时40分 1小时=60分钟 100/60def transform_minute(minute): hours = minute // 60 minutes = minute % 60 print(f'{minute}分钟可以转化为{hours}小时{minutes}分钟') return hours, minuteshours, minutes = transform_minute(200)print(f"hours is {hours}")print(f'200分钟可以转化为{hours}小时{minutes}分钟')print(transform_minute(200))

12.56200分钟可以转化为3小时20分钟hours is 3200分钟可以转化为3小时20分钟200分钟可以转化为3小时20分钟(3, 20)

四、函数的作用域,全局/局部变量

# 全局变量a = 1 # 不可变类型 想在函数内修改需要在前面加globall = [1, 2, 3] # 可变类型 不用global类型就可以在函数内修改def test1(): # a = 100 # 局部变量 global a a += 1 # 修改全局变量 l.append(4) print(l)def test2(): # a = 300 # 局部变量 print(a)test2()test1()print(a)

1[1, 2, 3, 4]2

五、函数的嵌套

def test1(): a = 10 print('test1开始执行') print(f'test1内部变量a的值是{a}') def test2(): # 内部函数修改外部函数的值,需要加nonlocal函数 # 函数内部修改不可变全局变量,需要加global函数 nonlocal a a = 100 print('test2开始执行') print(f'test2内部变量a的值是{a}') test2() print(f'test1内部变量a的值是{a}')test1()# test2() # 不能调用,只能在内部

test1开始执行test1内部变量a的值是10test2开始执行test2内部变量a的值是100test1内部变量a的值是100

六、函数的递归

大部分递归都可以用循环来代替

例子:算阶乘

def fact(n): if n == 1: return 1 result = n * fact(n-1) return result# 不能用太多递归次数,因为python用栈来存函数变量,如果函数太多,会导致栈溢出result = fact(3)print(result)

七、匿名函数lambda

lambda 形参: 函数体
(lambda 形参: 函数体)(实参)

# 常规函数def add(x, y): return x + y result = add(1, 2)print(result)# lambda 表达式expression = lambda x, y: x + yprint(expression(1, 2))# lambda 简单形式result = (lambda x, y: x + y)(1, 2)print(result)

八、匿名函数lambda的应用 在列表推导式中

# 列表推导式result = [x ** 2 for x in range(10)]print(result)# 列表推导式+函数def multiple(x): return x**2print([multiple(x) for x in range(10)])# 列表中使用lambdaprint([(lambda x:x**2)(x) for x in range(10)])

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81][0, 1, 4, 9, 16, 25, 36, 49, 64, 81][0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

sort函数中,默认实参是列表中每个元素

# sort函数 -- 用函数作keydef take_second(list_val):return list_val[1]list_value = [(5, 6), (7, 3), (1, 8)]list_value.sort(key=take_second)print(list_value)# sort函数 -- 用lambda作keylist_value.sort(key=lambda x: x[1], reverse=True)print(list_value)

[(7, 3), (5, 6), (1, 8)][(1, 8), (5, 6), (7, 3)]

九、匿名函数和常规函数对比

匿名函数是表达式,常规函数是语句

匿名函数为了简化代码,如果只调用一次可以使用

十、函数式编程的特点

# 不是函数式编程,因为同样的input,output不同def doubler1(l): for item in range(0, len(l)): l[item] *= 2 return llist_value = [1, 2, 3, 4, 5]print(doubler1(list_value))print(doubler1(list_value))# 是函数式编程def doubler2(l): new_list = [] for item in l: new_list.append(item * 2) return new_listlist_value = [1, 2, 3, 4, 5]print(doubler2(list_value))print(doubler2(list_value))

[2, 4, 6, 8, 10][4, 8, 12, 16, 20][2, 4, 6, 8, 10][2, 4, 6, 8, 10]

十一、函数式编程map()、filter()、reduce()函数
map()

# 方法一:函数def doubler(x): x *= 2 return x list_val = [1, 2, 3, 4, 5]result = map(doubler,list_val)print(list(result))# 方法二:lambdaresult = map(lambda x: x * 2, list_val)print(list(result))

filter()

# 方法一:函数def is_odd(x): # if x % 2 == 1: # return True # else: # return False return x % 2 == 1list_value = [1, 2, 3, 4, 5]result = filter(is_odd,list_value)print(list(result))# 方法二:lambdaresult = filter(lambda x: x % 2 == 1, list_value)print(list(result))

reduce()

from functools import reduce# 方法一:函数def add(x, y): return x + ylist_value = [1, 2, 3, 4, 5]result = reduce(add,list_value)print(result)# 方法二:lambdaresult = reduce(lambda x, y: x + y, list_value)print(result)

十二、函数式编程map() VS 列表推导式 形式上对比:
效率上对比:

列表推导式: 0-99个元素,一次性全部输出,占用内存大
map: 循环一次,输出一次,占用的内存小,效率更高

import timeitlist_time = timeit.timeit('[str(i) for i in range(100)]', number=10000)print(list_time)map_time = timeit.timeit('map(str,range(100))', number=10000)print(map_time)map_list_time = timeit.timeit('list(map(str,range(100)))', number=10000)print(map_list_time)

0.1504110830.00248724999999999640.126015125

总结
十二、函数是一等公民

# 1、赋值def func(message): print(f"Got a message:{message}")send_message = funcsend_message("welcome to DaXiong course") # func("welcome to DaXiong course")# 2、作为参数def get_message(message): return f"Got a message:{message}"def call(func, message): print(func(message))call(get_message, "welcome to DaXiong course")# 3、支持嵌套def func(message): def get_message(message): print(f"Got a message:{message}") return get_message(message)func("welcome to DaXiong course")# 4、返回值def func(): def get_message(message): return f"Got a message:{message}" return get_messagesend_message = func() # send_message = get_messagemessage_string = send_message("welcome to DaXiong course") # get_message()print(message_string)

Got a message:welcome to DaXiong courseGot a message:welcome to DaXiong courseGot a message:welcome to DaXiong courseGot a message:welcome to DaXiong course

十三、函数装饰器

import timedef my_decorator(func): def wrapper(): print("wrapper函数开始") start_time = time.perf_counter() func() end_time = time.perf_counter() print(f"函数运行时间:{end_time - start_time}") print("wrapper函数结束") return wrapper@my_decoratordef for_loop(): print("for_loop函数开始") for i in range(10000): pass print("for_loop函数结束")@my_decoratordef while_loop(): print("while_loop函数开始") i = 0 while i < 10000: i+=1 print("while_loop函数结束")# new_for = my_decorator(for_loop) # wapper# new_for()for_loop() # 相当于wapper()# new_while = my_decorator(while_loop)# new_while()while_loop() # 相当于wapper()

wrapper函数开始for_loop函数开始for_loop函数结束函数运行时间:0.00021966699999999978wrapper函数结束wrapper函数开始while_loop函数开始while_loop函数结束函数运行时间:0.0004706249999999988wrapper函数结束

十三、带参数的函数装饰器

import timedef my_decorator(func): def wrapper(number): print("wrapper函数开始") start_time = time.perf_counter() func(number) end_time = time.perf_counter() print(f"函数运行时间:{end_time - start_time}") print("wrapper函数结束") return wrapper@my_decoratordef for_loop(number): print("for_loop函数开始") for i in range(number): pass print("for_loop函数结束")@my_decoratordef while_loop(number): print("while_loop函数开始") i = 0 while i < number: i += 1 print("while_loop函数结束")# new_for = my_decorator(for_loop) # wapper# new_for(100000) # wapper(100000)for_loop(100000) # 相当于wapper(100000)# new_while = my_decorator(while_loop)# new_while()while_loop(100000) # 相当于wapper(100000)

wrapper函数开始for_loop函数开始for_loop函数结束函数运行时间:0.002143875wrapper函数结束wrapper函数开始while_loop函数开始while_loop函数结束函数运行时间:0.004666666999999999wrapper函数结束

十三、不定长参数的函数装饰器

import timeimport functoolsdef my_decorator(func): @functools.wraps(func) # 原函数的元信息拷贝的装饰器里,否则print(welcome)结果是wrapper def wrapper(*args, **kwargs): print("wrapper函数开始") start_time = time.perf_counter() func(*args, **kwargs) end_time = time.perf_counter() print(f"函数运行时间:{end_time - start_time}") print("wrapper函数结束") return wrapper@my_decoratordef welcome(*args, **kwargs): name, gender = args # if gender == "男": # gender = "先生" # else: # gender = "女士" gender = "男士" if gender == "男" else "女士" print(f"hi {name}{gender},welcome to daxiong course") print(f"{name}的年龄:{kwargs['age']}") print(f"{name}的爱好:{kwargs['hobby']}")welcome("Andy", "男", age="18", hobby="basketball")

十四、防止被装饰的函数改变

print(welcome.__name__) # welcome or wrapper

如果装饰器中含有:

@functools.wraps(func) # 原函数的元信息拷贝的装饰器里,否则print(welcome)结果是wrapper

则输出welcome,否则输出wrapper

十五、函数装饰器的嵌套

import functoolsdef decorator1(func): @functools.wraps(func) def wapper1(*args, **kwargs): print("执行装饰器1") func(*args, **kwargs) # wapper2() return wapper1def decorator2(func): @functools.wraps(func) def wapper2(*args, **kwargs): print("执行装饰器2") func(*args, **kwargs) # welcome() return wapper2@decorator1@decorator2def welcome(message): print(message)# new_welcome = decorator1(decorator2(welcome)) # 1 2 welcome的顺序# # decorator2(welcome) = wapper new_welcome = wapper1# new_welcome("welcome to daxiong course") # wapper1("welcome to daxiong course")welcome("welcome to daxiong course")

执行装饰器1执行装饰器2welcome to daxiong course

银行系统综合案例

import datetimeimport prettytable as pt # 将二维数组的打印美化成表格balance = 1000history = []# 小数点后不能超过2位def validate(func): def wrapper(*args, **kwargs): amount = str(args[0]) # 123.456 index = amount.index(".") if len(amount) - index - 1 > 2: print("格式输入错误") else: func(*args, **kwargs) return wrapper@validatedef deposit(account): global balance balance += account writeHistory(account, "存钱")@validatedef withdraw(account): global balance if account > balance: print("余额不足") else: balance -= account writeHistory(account, "取钱")def writeHistory(account, type): # 时间与格式化 d = datetime.datetime.now() create_time = d.strftime("%Y-%m-%d %H:%M:%S") if type == "存钱": money = f"+{account}" elif type == "取钱": money = f"-{account}" l = [create_time, type, money, "人民币", balance] history.append(l)def printHistory(): # print(history) newHistory = pt.PrettyTable() newHistory.field_names = ["交易日期", "摘要", "金额", "币种", "余额"] # 设置表格头 # newHistory.align["交易日期"] = "l" # newHistory.align["摘要"] = "r" # newHistory.align["币种"] = "l" for his in history: newHistory.add_row([his[0], his[1], his[2], his[3], his[4]]) print(newHistory)def show_menu(): info = '''操作菜单0:退出1:存款2:取款3:打印交易信息 ''' print(info)while True: show_menu() number = int(input("请根据菜单编号输入:")) if number == 0: print("退出") break elif number == 1: print("存钱") depositMoney = float(input("请输入要存贮的金额:")) deposit(depositMoney) elif number == 2: print("取钱") withdrawMoney = float(input("请输入要存贮的金额:")) withdraw(withdrawMoney) elif number == 3: print("查看交易日志") printHistory() else: print("输入错误")

prettytable将二维数组的打印美化成表格

import prettytable as pt# step1: 建立对象table = pt.PrettyTable()# step2: 设置表格头table.field_names = ["交易日期", "摘要", "金额", "币种", "余额"] # step3: 设置对齐方式table.align["交易日期"] = "l"table.align["摘要"] = "r"table.align["币种"] = "l"# step4: 添加行内元素for his in history: table.add_row([his[0], his[1], his[2], his[3], his[4]])print(table)

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。