0
点赞
收藏
分享

微信扫一扫

python函数高级【内置函数和推导式】23

拾光的Shelly 2022-04-19 阅读 70
python

python函数高级【内置函数和推导式】

1.函数嵌套

python中以函数为作用域,在作用域中定义的相关数据只能被当前作用域子作用域使用

1.1函数在作用域中

函数也是定义在作用域的数据

易错点:要注意作用域中的值在被调用时到底等于什么?

1.2函数定义的位置

函数可以定义在全局作用域,也可以定义在局部作用域,局部作用域定义的函数可以被局部作用域和其子作用域中调用(函数嵌套)

def func():
    name='wxy'
    print('我是外部函数')
    def inner():
        print('我是内部函数')
        print(name)
    inner()
func()
    	

为什么要函数嵌套?

当我们定义一个函数去实现某功能,将内部功能拆分成N个函数,担心这个N函数放在全局会与其他函数名冲突时,就可以用函数嵌套

def func():
    def f1():
        pass
    def f2():
        pass
    f1()
    f2()
func()

1.3函数嵌套引发的作用域问题

根据内存和执行过程分析作用域(分析函数执行过程).

作用域准则:

  • 优先在自己作用域找,没有去上级作用域找
  • 在作用域寻找值时,要确认此次的值为多少
  • 根据函数执行过程,确认函数作用域(函数嵌套)

2.闭包

闭包,将数据封装在一个包(区域)中,使用时再去取(本质上闭包是函数嵌套的特殊嵌套)

应用场景

  • 封装数据,防止污染全局
def func():
    #数据定义在函数内部
    name='wxy'
    def f1():
        pass
    def f2():
        pass
    f1()
    f2()
func()
  • 封装到一个包里面,使用时取
#调用func函数会在函数作用域中定义变量a,在调用函数inner,同局作用域就会找到变量a
def func(a):
    def inner():
        print(a)
    return inner
v1=func(1)
v2=func(2)
v1()
v2()

应用场景,基于多线程去下载视频

3.装饰器

不修改原函数的条件下,实现在函数执行前和执行后分别输出’before’ 和 ‘after’

def func():
    print("我是func函数")
    value = (11, 22, 33, 44)
    return value
result=func()
print(result)

装饰器推导过程

  • 过程1,添加函数嵌套
def func():
    print("我是func函数")
    value = (11, 22, 33, 44)
    return value
def outer(origin):
    def inner():
        print('before')
        #调用传入的函数
        res=origin()
        print('after')
        return res
    return inner
#func=outer(func)=inner
func=outer(func)
#func()=inner()
func()
  • 过程2,添加@函数名
def outer(origin):
    def inner():
        print('before')
        #调用传入的函数
        res=origin()
        print('after')
        return res
    return inner
# func=outer(func)
#Python中支持特殊语法,在某个函数上方使用@函数名(@outer),内部会自动执行@outer(func),执行完毕将返回值(inner)赋值给func
@outer
def func():
    print("我是func函数")
    value = (11, 22, 33, 44)
    return value
#func()==inner()
func()
  • 过程3添加参数
#传参
def outer(origin):
    def inner(*args,**kwargs):
        print('before')
        #调用传入的函数
        res=origin(*args,**kwargs)
        print('after')
        return res
    return inner
# func=outer(func)
@outer
def func(a1):
    print("我是func函数")
    value = (11, 22, 33, 44)
    return value
func(1)
  • 执行原函数
import functools
def outer(origin):
    @functools.wraps(origin)
    def inner(*args,**kwargs):
        print('before')
        #调用传入的函数
        res=origin(*args,**kwargs)
        print('after')
        return res
    return inner
# func=outer(func)
@outer
def func(a1):
    print("我是func函数")
    value = (11, 22, 33, 44)
    return value
func(1)
print(func.__name__)  #获取函数名称
print(func.__doc__)  #获取函数注释文本

补充:functools

装饰器实际上就是将原函数更改为其他函数,然后再此函数中再去调用原函数,要执行原函数,要用functools;

不用functools也可以实现装饰器的基本功能,后期项目开发,不加会报错,所以要规范写法

import functools
def outer(origin):
    @functools.wraps(origin)
    def inner(*args,**kwargs):
        print('before')
        #调用传入的函数
        res=origin(*args,**kwargs)
        print('after')
        return res
    return inner
# func=outer(func)
@outer
def func(a1):
    print("我是func函数")
    value = (11, 22, 33, 44)
    return value
func(1)
print(func.__name__)
print(func.__doc__)

总结:装饰器,在不修改原函数内容的前提下,通过@函数可以实现在函数前后自定义执行一些功能(大量操作使用)

装饰器

  • 实现原理:基于@语法和函数闭包,将原函数封装在闭包中,然后将内部函数赋值为一个新的函数(内层函数),执行函数时(就会执行内层函数)再在内层函数中执行闭包中的原函数
  • 实现效果:可以在不改变原函数内部代码调用方式的前提下,实现在函数执行和执行扩展功能
  • 适用场景:多个函数统一在执行前后执行自定义的相同功能
import functools
def outer(origin):
    @functools.wraps(origin)
    def inner(*args,**kwargs):
        #执行前
        res=origin()
        #执行后
        return res
    return inner
@outer
def func():
    pass
func()

应用场景,编写网站时,有很多个页面都需要登录才能访问,可基于装饰器验证用户

4.匿名函数

匿名函数,基于lambda表达式实现定义一个可以没有名字的函数

data=lambda x:x+100
data(10) #110

lambda定义的函数格式:lambda 参数:函数体

  • 参数,支持任意参数

    lambda x:函数体
    lambda a1,a2:函数体
    lambda *args,**kwargs:函数体
    
    
  • 函数体,只支持单行代码

    lambda x:x+100
    
  • 返回值,默认将函数体单行代码执行的结果返回给函数的执行者

    data=lambda x:x+100
    data(10) #110
    

匿名函数只用于简单的业务处理,可以快速创建简单函数

编写匿名函数时,由于函数体只能写一行,所以匿名函数只用于简单的业务处理

扩展功能

简单条件语句,可以基于三元表达式实现

结果=条件成立时 if 条件 else 条件不成立时
num=input('请输入数字')
data='大了' if int(num)>6 else '小了'
print(data)

匿名函数和三元表达式结合使用

data=lambda x:'大了' if x>6 else '小了'
print(data(1))

5.生成器

生成器是由函数+yield关键字创造出来的写法,在特定情况下,可以节省内存

  • 生成器函数,在函数中存在yield,这个函数就是生成器函数

    def func():
        print(1)
        yield 1
        print(2)
        yield 2
    
  • 生成器对象,执行生成器函数时,会返回一个生成器对象

    def func():
        print(1)
        yield 1
        print(2)
        yield 2
        print(3)
    data=func()
    

    注意:执行生成器函数时,函数内部代码不会执行

    def func():
        print(1)
        yield 1  #像return,执行到这个位置,不会执行
        print(2)
        yield 2
        print(3)
        yield 3
        print(4) #最后通过next(data)会报错,StopIteration
    data=func()
    # next(data)
    # next(data)
    # next(data)
    #for循环执行生成器对象,不会报错
    for i in data:
        print(i)
    
    

应用场景

  • 数据量大,无法存储,要多少取多少,例:生成300w个随机4位数,并打印

    import random
    def get_random_num(max_count):
        counter=0
        while counter<max_count:
            #获取4位随机验证码
            yield random.randint(1000,9999)
            counter+=1
    data_list=get_random_num(3000000)
    #使用几个取几个
    

扩展

def func():
    print(111)
    v1=yield 1  #v1接收字下一次传入的值
    print(v1)

    print(222)
    v2=yield 2
    print(v2)

    print(333)
    v3=yield 3
    print(v3) #最后通过next(data)会报错,StopIteration

    print(444)

data=func()
#第一个必须传入None,n1接收yeild返回的值
n1=data.send(None)
print(n1)

n2=data.send(1000)
print(n2)

n3 = data.send(777)
print(n3)

#没有人接收了,报错StopIteration
n4 = data.send(888)
print(n4)

6.内置函数

在这里插入图片描述

  1. abs,取绝对值
  abs(-1)   1
  1. pow,指数
  pow(2,5)   2**5
  1. sum,求和
  sum([1,2,3])   6
  1. divmod,求商和余数
  s1,s2=divmod(9,2)    4,1
  1. round,小数点后n位(四舍五入)
  round(3.1415926,3)    3.142
  1. min,最小值
  min([1,2,3,-1,-100,123])  -100
  1. max,最大值
  max([1,2,3,-1,-100,123]) 123
  1. all,是否全为True
  all([1,2,False])   False
  1. any,是否存在True
  any([1,2,False])   True
  1. bin,十进制转二进制
  2. oct,十进制转八进制
  3. hex,十进制转十六进制
  4. ord,获取unicode码点(十进制)
  v1=ord('王')
  print(v1,hex(v1))  29579 0x738b
  1. chr,根据码点(十进制)获取对应字符
  v1=chr(29579)
  print(v1)
  1. int
  2. float
  3. str,unicode编码
  4. bytes,utf-8,gbk编码
  5. bool
  6. list
  7. dict
  8. tuple
  9. set
  10. len,求长
  11. print,打印
  12. input,输入
  13. open,打开文件
  14. type,判断数据类型
  15. range,生成数字
  16. enumerate,循环,有索引
  17. id,求内存地址
  18. hash,判断是否可哈希
  19. help,查看帮助文档
  20. zip
   v1=[1,2,3]
   v2=[11,22,33,44]
   v3=[111,222,333,444,555]
   #取最短的,生成一个元组
   for item in zip(v1,v2,v3):
       print(item,type(item))
   (1, 11, 111) <class 'tuple'>
   (2, 22, 222) <class 'tuple'>
   (3, 33, 333) <class 'tuple'>
  1. callable,是否可执行,加()可以执行
  2. sorted,排序,多种数据类型都可排序,sort只可以排序列表
   info = {
       "wupeiqi": {
           'id': 10,
           'age': 119
       },
       "root": {
           'id': 20,
           'age': 29
       },
       "seven": {
           'id': 9,
           'age': 9
       },
       "admin": {
           'id': 11,
           'age': 139
       },
   }
   result=sorted(info.items(),key=lambda x:x[1]['id'])
   print(result)
   data_list = [
       '1-5 编译器和解释器.mp4',
       '1-17 今日作业.mp4',
       '1-9 Python解释器种类.mp4',
       '1-16 今日总结.mp4',
       '1-2 课堂笔记的创建.mp4',
       '1-15 Pycharm使用和破解(win系统).mp4',
       '1-12 python解释器的安装(mac系统).mp4',
       '1-13 python解释器的安装(win系统).mp4',
       '1-8 Python介绍.mp4', '1-7 编程语言的分类.mp4',
       '1-3 常见计算机基本概念.mp4',
       '1-14 Pycharm使用和破解(mac系统).mp4',
       '1-10 CPython解释器版本.mp4',
       '1-1 今日概要.mp4',
       '1-6 学习编程本质上的三件事.mp4',
       '1-18 作业答案和讲解.mp4',
       '1-4 编程语言.mp4',
       '1-11 环境搭建说明.mp4'
   ]
   #排序
   result=sorted(data_list,key=lambda x:int(x.split(' ')[0].split('-')[-1]))
   print(result)

7.推导式

推导式可以通过一行代码实现创建list,dict,tuple,set,并同时初始化一些值

  • 列表

    #生成列表
    data_list=[ i for i in range(10)]
    print(data_list)   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    #生成列表套列表
    data_list=[ [i,i+1] for i in range(5)]
    print(data_list)           [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]
    #生成列表,做条件判断
    data_list=[ i for i in range(10) if i>3]
    print(data_list)   [4, 5, 6, 7, 8, 9]
    
  • 集合

    #生成集合
    data={i for i in range(10)}
    print(data)  # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    #生成集合套元组
    data={(i,i+1) for i in range(5)}
    print(data)        #  {(0, 1), (1, 2), (3, 4), (2, 3), (4, 5)}
    #生成集合,做条件判断
    data={ i for i in range(10) if i>3}
    print(data)  # {4, 5, 6, 7, 8, 9}
    
  • 字典

    #生成字典
    data={i:i for i in range(4)}
    print(data)  # {0: 0, 1: 1, 2: 2, 3: 3}
    #生成字典
    data={i:(i,i+1) for i in range(3)}
    print(data)        # {0: (0, 1), 1: (1, 2), 2: (2, 3)}
    #生成字典,做条件判断
    data={ i:i for i in range(6) if i>3}
    print(data)  # {4: 4, 5: 5}
    
  • 元组,不同于其他类型

    #生成元组
    data=(i for i in range(4))
    print(data)  # <generator object <genexpr> at 0x00000218A9AABB30>
    for i in data:
        print(i)
    0
    1
    2
    3
    

推导式小高级

  1. 推导式支持嵌套

    data = [ (i,j) for j in range(5) for i in range(10)]
    

https://www.luffycity.com/

举报

相关推荐

0 条评论