ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

python入门学习(三)

python入门学习(三) # ******** python中的函数 ******** # from email.contentmanager import maintype # from email.contentmanager import maintype from itertools import count # 1.什么是函数 # 函数是组织好的可重复使用的、用来实现单一或者相关联功能的代码段 # 比喻函数就像厨具里的破壁机 你不需要知道内部的刀片是怎么转的只需要放入水果输入按下开关执行它就会给你出果汁输出结果 # 2.函数的作用 # 代码复用写一次代码到处运行不用重复造轮子 # 易于维护如果逻辑要改只需要改函数内部所有调用的地方都会更新 # 结构清晰把复杂的程序拆分成一个个的小模块让代码可读性更强 # 3.定义函数的基本格式 # def 函数名(参数1,参数2,..。): # 函数的代码段 (具体要干活的代码) # return 结果 # 注意⚠必须按照缩进来写函数python中的缩进决定了代码的作用域 # 参数是外界传给函数内部的信息 # 形参形式参数定义函数时写的参数名 # 实参实际参数调用函数时真正传进去的值 # 代码举例 # def say_hello(name): # name 就是形参 # print(f您好{name}) # say_hello(未来) # 未来 就是实参 # 3.1 一个完整的自定义函数由以下几部分组成 # def nasa(parameter1, parameter2) - str: # # 这里是 Docstring字符串文档 # 解释函数是做什么的参数是什么返回值是什么 # # # 逻辑代码块 # result f{parameter1}{parameter2} # # return result # 返回值 # 关键细节 # 1.函数名它是指向函数对象的变量名 # 2.参数parameters函数定义的占位符 # 3.类型注释如 - str它不会强制限制类型但对IDE提醒和团队协作至关重要 # 3.2 参数的四种形态 # 1.位置参数按顺序一一对应 # 2.关键字参数nasa(namelisi),不按顺序也没关系 # 3.默认参数def nasa(a10) 切记默认参数必须返回位置参数后面 # 4.不定长参数 # 4.1 *args可变长元组接收多出来的的位置参数打包成元组tuple # 4.2 **kwargs可变长字典接收多出来的关键字参数打包成字典dict # 4.函数执行的底层逻辑找帧stack frame # 当你调用一个函数python解释器会发生什么 # 1.创建栈帧在内存中开辟一块空间用来存放该函数的局部变量参数等 # 2.压栈将这个栈帧压入调用栈 # 3.执行运行函数体代码 # 4.出栈函数体执行完毕遇到retur或代码结束将栈帧被销毁释放内存 # 这就是为什么函数内部的局部变量外面无法访问的原因因为随着函数结束存放这些变量的空间已经被拆除了 # 返回值 retur # 在python中每一个函数都有返回值 # 1.如果你写了 return x它返回 x # 2.如果没写 return或者只写了return后面没接东西它隐式返回 None # 3.python 可以返回多个值例如 return a,b 本质上它是返回了一个包含 a 和 b 元组tuple # 5.什么时候该写函数 # 复用性一段逻辑出现了两次以上请封装它 # 单一职责一个函数只做一件事如果你的函数超过50行通常意味着它承担着太多的责任需要进行拆分 # 纯函数理想状态下相同的输入永远得到相同的输出且不修改外包的局部变量这种函数是最容易测试和维护的 # 单个参数 # def nasa(name): # # :param name: 姓名中文/英文 # :return: # # print(我是浦东 name) # 函数调用 # if __name__ __main__: # nasa(吴彦祖) # if __name__ __main__: # 这个主函数是函数的入口 # __name__代表当前模块 # __main__代表被运行模块 # 如果 当前模块 和 被运行模块 相等就运行不相等就不允许 # 多个参数 # def nasa(name, age): # # :param name: # :param age: # :return: # # print(我是浦东 name 我今年 age 岁了) # # if __name__ __main__: # nasa(吴彦祖, 18) # 默认参数 # def nasa(name老六,age18): # # :param name: # :param age: # :return: # # print(我是浦东 name 我今年 age 岁了) # # if __name__ __main__: # nasa(name吴彦祖) # 可变长元组 * # def nasa(*args): # * 就是专门处理散装的、按顺序排列的值可传多个固定值 # *args指的是把所有传进来的。没有指定名字的参数通通塞进一个元组里 # # :param values: # :return: # # print(args) # # if __name__ __main__: # nasa(zhangsan,lisi,laoliu) # 可变成字典 ** # def nasa(**kwargs): # **kwargs 指的是把所有传进来的。带有名字的参数通通打包成一个字典 # # kw: 代表 keyword关键字 args代表arguments参数 # :param kwargs: # :return: # # print(kwargs) # # dcs { # name: zahangsan, # age: 18, # sex: 1 # } # # if __name__ __main__: # nasa( name吴彦祖, age18) # def nasa(*args,**kwargs): # print(f位置参数元组{args}) # print(f关键字参数字典{kwargs}) # # if __name__ __main__: # nasa(1,2,3, name吴彦祖, age18) # python中的返回值 # print()输出的是一个不可改变的结果return输出的是一个可供调用的变量 # def nasa(a): # b a 1 # print(b) # return b # # # if __name__ __main__: # bell nasa(3) # print(bell) # ******** python中的作用域 ******** # 作用域scope规则变量在哪里定义就在哪里起作用如果到处都有那就由进及远找 # 在python中这套原则被称为LEGB原则 # 1.LEGB变量的查找顺序 # 当你在函数中去使用一个变量名时python会按照以下顺序在四个仓库里去查找一旦找到就停止搜索如果全找完都没有那么会报错 NameError # 1.1 L (local)-局部作用域函数内部定义的变量 # 1.2 E (Enclosing) - 嵌套闭包作用域外部函数里但不在内部函数里的变量 # 1.3 G (Global) - 全局作用域模块最顶层定义的变量通常是文件开头写的 # 1.4 B (Built-in) - 内置作用域python自带的函数如 len、print、int等 # 场景演示谁才是个角色 # x 全局变量 # def outer(): # x 嵌套变量 # # def inner(): # x 局部变量 # print(f我在 inner 里我看到的是{x}) # 我在 inner 里我看到的是局部变量 # # inner() # print(f我在 outer 里我看到的是{x}) # 我在 outer 里我看到的是嵌套变量 # if __name__ __main__: # outer() # print(f我在最外面我看到的是{x}) # 我在最外面我看到的是全局变量 # 3.只读不改作用域的 屏障 # 这是最核心的重点在函数内部你可以直接读取全局变量的值但不能直接改变它 # 如果你尝试修改python会以为你想在函数里创建一个同名的局部变量从而引发混乱 # 错误❌示范 # count 0 # def nasa(): # count count 1 # 报错UnboundLocalError # # python 认为你在引用局部变量但还没定义它 # # if __name__ __main__: # nasa() # 4.破壁术global 和 nonlocal # 如果你非要在函数内部修改外部的变量你需要申请 通行证 # 修改全局变量: global # count 0 # def nasa(): # global count # 声明 我要东外面那个 count # count 5 # if __name__ __main__: # nasa() # print(count) # 5 # 修改嵌套变量nonlocal # 这在闭包函数嵌套函数中非常有用 # def nasa(): # money 10 # def bell(): # nonlocal money # money 100 # bell() # print(money) # # if __name__ __main__: # nasa() # 5.为什么作用域这么重要 # 5.1 避免污染如果没有作用域全部的变量名都不能重复你在函数a用了i函数b里的i会被误改 # 5.2 内存回收当函数执行完L(局部变量)所在的仓库就会被销毁去释放内存如果里面所有的东西都是全局电脑内存很快就会爆掉 # 如果你在函数里写了 len 哈哈然后又想用 len([1,2])会发生什么 # 答案python会在L找len发现它是一个字符串于是报错说字符串不能当函数去调用这就是局部变量屏蔽了内置函数 # 6.什么是闭包函数的进阶用法 # 闭包本质也是一个函数但比普通函数多了一个 随身背包这个背包里面装的是它被创建时周围环境的变量 # 专业定义 # 如果一个内部函数引用了外部函数的变量并且外部函数返回了这个内部函数那么这个内部函数连同它引用的变量就组成了一个闭包 # 7.为什么要用闭包 # 7.1 数据封装在全局定义的变量谁都能改不安全闭包里的变量只要内部函数能访问 # 7.2 保持状态普通函数运行完内部变量就 失忆了闭包能让变量在多次调用直接持续存在 # 7.3 减少参数冗余如果你有一个参数在很多次调用都是一样的闭包可以帮你 预设好这个参数 # 8.怎么使用闭包 # 场景计算历史所有输入的平均值 # def make_avgrager(): # # 1.外部函数的局部变量 # series [] # series: [10,11] # # def avgrager(new_value): # new_value: 11 # # 2.内部函数引用了外部变量 # series.append(new_value) # total sum(series) # tatal: 21 # return total / len(series) # # # 3.返回内部函数不带括号 # return avgrager # # if __name__ __main__: # avg make_avgrager() # print(avg(10)) # print(avg(11)) # print(avg(12)) # 场景加法器 # 外函数传一个底数内函数负责把新数加在底数上 # def box(num1): # # num1 是外函数的变量 # def add(num2): # # 内函数引用了 num1 # return num1 num2 # # return add # # if __name__ __main__: # # 1.创建一个 加10 的机器 # add10 box(10) # 输出15 (105) # # 2.创建一个 加100 的机器 # add100 box(100) # 输出105 (1005) # print(add10(5)) # print(add100(5)) # 1.num1 是怎么拿到值的 # num1 的值是在创建机器的时候就被 缝进去了 # 动作当你写 add10 box(10),你就调用了 box # 发生过程box 接收到了数字10把它存在自己的变量 num1此时它发现内部的add函数需要用到这个 num1 # 结果在 add被扔出来(return)的那一刻python自动给add10做了一个随身口袋把10塞了进去 # 结论num1 是add10诞生时就自带的 出厂设置它不需要你后来告诉它它一直随身带着 # 2.num2 是怎么拿到值的 # 动作在你写add(5)你实际上是在给这个已经成型的机器 喂 数据 # 发生过程这里(5)就是直接给add函数也就是现在add10的第一个位置参数 # 结果此时add开始工作它把传进来的5 放在了定义的num2这个位置上 # num2是一个 临时工 这次你传5它就是5你下次传8它就是8 # 3.它们是怎么合体的 # 当add10(5)运行到return num1 num2 这一行的时候它会做两件事 # 3.1 翻口袋它从随身口袋摸出那个早就在那里的10也就是num1 # 3.2 看手心它看看你刚喂给它的那个5也就是num2 # 3.3 做加法10 5 15 # 9.匿名函数 # 什么是匿名函数? # 在python中匿名函数使用 lambda关键字定义它被称为 匿名函数或 一行函数因为它不需要用def取名 # 基本格式 # lambda 参数1,参数2,... 表达式 # 9.2怎么使用 # 先定义一个普通函数来看一下和匿名函数的区别 # def add(x,y): # return x y # if __name__ __main__: # print(add(1,1)) # 匿名函数 # nasa lambda x, y :x y # print(nasa(1,1)) # 什么时候使用匿名函数 # 用完即丢这个逻辑这里只用一次专门去def一个函数太费劲 # 代码简洁但逻辑非常简单一行搞定时lambda让代码看起来更清爽 # num [1,2,3,4] # # 把每个数求平方 # nasa map(lambda x:x * x,num) # print(list(nasa)) # 10.函数的传递 # 需求编写一个求平均值的函数然后根据各科成绩平均分判断是否为优秀学生(分数≥80为优秀学生) # def avg_score(num): # score num / 6 # return score # # def score(fs): # 函数传递 # value avg_score(fs) # if value 80: # print(优秀学生) # else: # print(不是优秀学生) # # if __name__ __main__: # score(400) # 第一题【外卖后台自动调价系统】 # 1. 场景背景 # 你正在为“饿了么”编写一个订单结算函数。 # 后台接收到的数据比较杂乱既有店铺名称也有顾客备注的一些赠品没有价格还有真正的计价菜品有键值对价格。 # 2. 业务规则输入 # shop_name字符串代表店铺名字必须接收。 # *foods接收所有“只提名字、不计金额 ”的赠品或餐具如筷子, 纸巾, 赠送小菜 # **prices接收所有“菜品名价格”的计价对如pizza88, coke12。 # 3. 逻辑处理过程 # 计算总价只累加 prices 里的金额忽略 foods 里的赠品。 # 满减政策如果计算出的总金额 满 100 元系统自动判定为大额订单给予 8 折 优惠。 # 打印清单在函数内部打印出店名和所有获赠的赠品清单。 # 4. 任务结果输出 # 返回最终客户需要支付的结算金额浮点数。 # 5、输出示例 # --- 正在处理【好味小吃店】的订单 --- # 备注赠品: 多加辣 / 要餐具 # 订单A结算金额: 40 元 # # --- 正在处理【必胜客】的订单 --- # 备注赠品: 不要吸管 # 系统消息订单满100元已触发8折优惠 # 订单B结算金额: 96.0 元 # def nasa_order(shop_name, *foods, **prices): # # :param shop_name: 店铺名称 # :param foods: 赠品或者备注*args - 元组 # :param prices: 菜品以及价格**kwargs - 字典 # :return: # # print(f--- 正在处理【{shop_name}】的订单 ---) # # 1.处理赠品清单 # if foods: # print(f备注赠品{/.join(foods)}) # else: # print(f备注赠品无) # # # 2.计算总价(**kwargs) # # prices.values() 拿到字典里所有价格的数字 # total_price sum(prices.values()) # # 3.执行满逻辑 # if total_price 100: # print(系统消息订单满100元已触发8折优惠) # total_price total_price * 0.8 # return round(total_price,2) # 保留小数前两位 # # if __name__ __main__: # order_A nasa_order(好味小吃店,多加辣/要餐具,pizza20, coke20) # print(f订单A结算金额{order_A}元) # print(f订单A结算金额{order_A:.2f}元) # 保留小数后两位 # order_B nasa_order(必胜客, 不要吸管, pizza80, coke40) # print(f订单B结算金额{order_B}元) # 第二题【万能智能插座系统】 # 1. 场景背景 # 想象你正在开发一款智能家居控制中心的底层逻辑。 # 你的中心有一个** 万能插座 **主函数它本身并不关心插在上面的是什么电器。 # 它的唯一职责是检测电流 - 接通电源 - 触发电器开关。 # 2. 角色分工逻辑拆解 # 指令集子函数/电器这是具体的执行逻辑。不同的电器有不同的工作反馈但它们都等待着被 启动。 # 调度中心主函数/插座这是一个 高阶容器。它预留了一个接口参数名等待你把某个电器的 启动指令传进去。 # 3. 业务规则任务要求 # 步骤 A定义电器逻辑 # 定义 start_fan()打印 “ [风扇] 接收到电流叶片开始转动...”。 # 定义 start_lamp()打印 “ [台灯] 接收到电流灯丝开始发光...”。 # 步骤 B定义调度逻辑 # 编写主函数 power_strip(device_func)。 # 处理流程 # 1、打印 “⚡ [系统] 检测到设备接入正在安全通电...” # 2、执行传进来的 device_func。 # 3、打印 “✅ [系统] 设备运行稳定。” # 步骤 C模拟运行 # 分别演示如何通过 “插座” 来启动 “风扇” 和 “台灯” # 示例输出 # ⚡ [系统] 检测到设备接入正在安全通电... # [风扇] 接收到电流叶片开始转动... # ✅ [系统] 设备运行稳定。 def start_fan(): print( [风扇] 接收到电流叶片开始转动...) def start_lamp(): print( [台灯] 接收到电流灯丝开始发光...) def power_strip(device_func): print(⚡ [系统] 检测到设备接入正在安全通电...) device_func() print(✅ [系统] 设备运行稳定。) if __name__ __main__: print(f---- 正在测试风扇 ----) power_strip(start_fan) print(f---- 正在测试台灯 ----) power_strip(start_lamp)
返回列表