匿名函数+模块
内容概要
- 匿名函数lambda
- map+filter+reduce
- 面向过程编程
- 模块介绍
- 模块的搜索路径
- 循环导入问题
- 区分py文件的两种用途
内容详细
-
匿名函数lambda
# 1.def用于定义有名函数 # func = 内存地址 def func(x,y): return x+y # 2.lambda用于定义匿名函数 lambda x,y:x+y # 3.如何调用匿名函数: # 方式一:内存地址() lambda x,y:x+y = 内存地址 res = (lambda x,y:x+y)(1,2) print(res) # 方式二:很愚,不如直接用有名函数 func = lambda x,y:x+y res = func(1,2) print(res) # 方式三:匿名函数用于临时调用一次的场景,更多的是将匿名函数与其他函数配合使用 # ps:匿名函数在定义阶段就被当垃圾回收了,索引为0 # 案例: salaries = { 'egon':5, 'jason':4.5, 'alex':3, 'lxx':4.7 } # 需求:找出薪资最高的那个 res = max([1,2,3,4]) print(res) # 4 # max的用法 # 方法一:有名函数def def func(k): return salaries[k] res = max(salaries,key=func) print(res) # 方法二:匿名函数lambda res = max(salaries,key=lambda k:salaries[k]) print(res) res = min(salaries,key=lambda k:salaries[k]) print(res) # 找工资最少 res = socted(salaries,key=lambda k:salaries[k]) print(res) # 排序 -
map+filter+reduce
# 了解 # map的应用 l = ['ycc','xixi','haha','xiha'] # 给名字加个后缀_aaa new_l = [name+'_aaa' for name in l] print(new_l) res = map(lambda name:name+'_aaa',l) # 映射 l中每一个值都会加后缀迭代 print(res) # <map object at 0x000002E87FBB1070> 生成器 # filter的应用 l = ['ycc_aaa','xixi_aaa','haha','xiha'] print([name for name in l if name.endswith('_aaa')]) print(filter(lambda name: name.endswith('_aaa'), l)) # <filter object at 0x00000234A39E1070> # reduce的应用 from functools import reduce print(reduce(lambda x, y: x + y,[1, 2, 3], 11)) # 17 # 原理 取两个值11+1,然后再取两个值12+2,再14+3 print(reduce(lambda x, y: x + y,['a', 'b', 'c'], 'e')) # eabc 与上面原理一样 -
面向过程编程
""" 1、面向过程编程思想 过程就是流程,即先干什么再干什么后干什么 基于该思想写程序就好比在设计一条条的流水线 优点:复杂的问题流程化、进而简单化 缺点:牵一发而动全身,扩展性差 """ -
模块介绍
''' 一、模块的介绍 模块就是一系列功能的集合体,分为三大类 1.内置的模块 2.第三方的模块 3.自定义的模块 一个python文件本身就是一个模块,文件名 m.py ,模块名 m ps:模块分为四种模式 1.使用python编写的.py文件 2.把一系列模块组织到一起的文件夹(注:文件夹下有一个_init_.py文件,该文件夹称之为包) 3.已编译为共享库或DLL的C或C++扩展 4.使用C编写并链接到python解释器的内置模块 二、为何要用模块 1.内置与第三方的模块拿来就用,无需定义,这种拿来主义,可以极大的提升自己的开发效率 2.自定义的模块 可以将程序的部分功能提取出来放到一个模块中为大家共享使用 好处是介绍了代码冗余,程序组织结构更加清晰 三、如何用模块 ''' ''' foo.py文件的内容: x=1 def get(): print(x) def change(): global x x=0 ''' # 一、如何用模块 # import ... # 1.首次模块导入会做三件事: # 1、执行源文件代码 # 2、产生一个新的名称空间用于存放源文件执行过程中产生的名字 # 3、在当前执行文件所在的名称空间中得到一个名字foo,该名字指向新创建的模块名称空间, # 若要引用模块名称空间中的名字,需要加上该前缀 # 需要强调一点是,第一次导入模块已经将其加载到内存空间了,之后的重复导入会直接引用内存中已存在的模块, # 不会重复执行文件,通过import sys,打印sys.modules的值可以看到内存中已经加载的模块名。 # import sys # print(sys.modules) # # 'foo': <module 'foo' from 'D:\\Users\\ycc\\PycharmProjects\\pythonProject\\day 13\\foo.py'>} # 2.引用 # 强调一: # 加上foo.作为前缀就相当于指名道姓地说明要引用foo名称空间中的名字, # 所以肯定不会与当前执行文件所在名称空间中的名字相冲突,并且若当前执行文件的名称空间中存在x, # 执行foo.get()或foo.change() # 强调二:无论是查看还是修改都是以原模块为基准的,与调用位置无关 # 例: # x = 100 # import foo # foo.x # 这里虽然定义了变量x,但是foo.x 输出结果仍为 1 # foo.get() # foo.change() # 二:导入模块的模式与规范 # 模式 # 1.可以improt语句导入多个模块(推荐使用) # import a # import b # ... # 2.在一行导入,用逗号分隔开不同的模块(不推荐) # import a,b,c,... # 规范(按以下顺序导入模块,虽然不按顺序也不会报错,但是算是自发的规定) # 1.内置模块 # 2.第三方模块 # 3.自定义模块 # 其他导入语法 # import foo as f # 注:这里as f后不要加冒号 # # 这里相当于把foo换个名字,因为可能会遇到名字特别长的模块名,为了调用时方便,可这样操作 # f.x # 等价与foo.x # f.get() # f.change() # 模块是第一类对象 # 自定义模块的命名应该采用纯小写+下划线的风格(python3中) # python2中是驼峰体的风格 # from 模块 import 模块内的功能 from foo import x,get,change #将模块foo中的x和get导入到当前名称空间 a=x #直接使用模块foo中的x赋值给a get() #直接执行foo中的get函数 change() #即便是当前有重名的x,修改的仍然是源文件中的x ''' 无需加前缀的好处是使得我们的代码更加简洁, 坏处则是容易与当前名称空间中的名字冲突, 如果当前名称空间存在相同的名字,则后定义的名字会覆盖之前定义的名字。 ''' # *:导入模块中的所有名字 # from foo import * # print(x) # print(get) # print(change) # *也不推荐使用 # name = 'egon' # from foo import * # print(name) # 此时如果*里也有name,则会将egon覆盖掉,但是你只知道导入了所有模块,并不清楚有没有name模块 -
模块的搜索路径
# 无论是import还是from...import...在导入模块时都涉及到查找问题 # 模块搜索路径,优先级从高到低 # 1、内存 # 2、内置 # 3、sys.path import sys print(sys.path) # 值为一个列表,存放了一系列的文件夹 # 其中第一个文件夹是当前执行文件所在的文件夹 # 例: import time import spam # 导入模块到内存 print(spam.money) time.sleep(10) # 在这10秒内将spam.py文件删除 import spam # 10秒后,仍能调用,说明是从内存中找的 print(spam.money) # 代码运行结束后可在运行一次,会发现报错找不到spam.py # 不在同一个文件内,想调用另一个文件内的模块 # 方法一: import sys print(sys.path) sys.path.append(r'D:\py18期\day26\代码\aaa') # 想调用文件的模块 import spam # 方法二: from aaa.bbb.ccc import spam # 导入语句中出现的点,代表路径分隔符 # spam.money # 使用语句中出现的点,代表问某一个名称空间要名字 -
循环导入问题
# 现在有三个py文件 m1.py m2.py run.py # m1.py文件内容 import m2 from y print(y) x = 111 # m2.py文件内容 import m1 form x print(x) y = 222 # run.py文件内容 import m1 # 现在执行run.py # 1.首先 import m1 创建了m1的名称空间,执行m1.py, # 2.import m2 from y 注意这里先 import m2创建了m2的名称空间还未执行from y(调用m2中的y) # 3.创建m2的名称空间后,执行m2.py,import m1(已经创建过m1的名称空间),执行from x 但是m1.py中只执行了import m2,根本 # 还没有定义x = 111,所以这里找不到x,报错 # 修改方案一: # 将x = 111,y = 222提到最上面,执行m1,m2两个py文件时,先将x,y定义好 # 修改方案二: # m1.py文件内容 def f1(): import m2 from y print(y) x = 111 # m2.py文件内容 def f2(): import m1 form x print(x) y = 222 # run.py文件内容 import m1 m1.f1() # 运用函数定义阶段不执行代码的特点解决这个问题 -
区分py文件的两种用途
# 一个python文件有两种用途 # 1.被当作程序运行 # 2.被当作模块导入 # print(__name__) # __main__ # 1.当foo.py被运行时,__name__的值为'__main__' # 2.当foo.py被当作模块导入时,__name__的值为'foo' if __name__ == '__main__': print('文件被执行') get() change() else: # 被当作模块导入时做的事 print('文件被导入') pass # 格式: # m1.py def f1(): print('xxxxxxxxxxxxxxxxx') # f1() # if __name__ == "__main__": # f1() # run.py import m1 def start(): pass if __name__ == '__main__': start()

浙公网安备 33010602011771号