匿名函数+模块

内容概要

  • 匿名函数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()
    
posted @ 2021-07-05 16:00  ccFTD  阅读(51)  评论(0)    收藏  举报