• 小白学习之路,基础四(函数的进阶)


    一,内置函数

    前面已经认识了函数,对函数都有所了解了,其实呢,在Python中提供了很多内置的函数方便给我们调用。下面会给大家提到一些常用的常用内置函数的用法,当然还有一些其他没讲到的,你也可以看参考文档,深入学习一波。咳咳咳,不多说了,直接进入装逼的代码环节。

    更多的内置函数详情请参考http://www.runoob.com/python3/python3-built-in-functions.html

     1 abs(-3)  #取绝对值
     2 all([1,2,5,0])  #当全部为真或者全部不为0时,返回为真(一假全假)
     3 any([0,1,0,]) #判断是否有一个为真,存在就为真(一真全真)
     4 type('123') #返回数据类型
     5 bin(10)  #把数字转换为二进制
     6 oct(10)  #把数字转换为8进制
     7 hex(17)  #数字转换为16进制
     8 chr(65) #里面是ASCII码的序号,然后转化为相应的ASCII里面的值,这个在做随机验证码有用到哦
     9 ord('A') #跟chr相反,是把ascii码里面的值转化为对应的序号
    10 a=dict() #生成字典
    11 dir(a) #查看字典可以调用的方法
    12 int('1') #转换为整数类型
    13 str(1) #转换为字符串类型
    14 divmod(5,3) #输出商和余数
    15 a=lambda n:n*n #匿名函数
    16 #输出0-19所有偶数
    17 def calc(n):
    18     return n%2==0
    19 c=filter(calc,range(20))#根据前面的方法,在后面值中筛选正确的结果。
    20 for i in c:
    21     print(i)
    22 locals() #打印局部变量
    23 globals() #打印全局变量
    24 pow(2,3) #2的三次方
    25 __import__('time') #在记不住库准确名字的时候使用
    26 #eval()能把字符串转化为字典或者列表
    27 s1="[1,2,'fa']"
    28 l=eval(s1) #把字符串转化为列表
    29 
    30 s2="{'name':'zzq','age':'18'}"
    31 d=eval(s2) #把字符串转化为字典
    View Code

    当然还有很多的内置函数,如果你感兴趣,可以进一步去探索。

    二,列表生成式

    列表生成式,听名字感觉是生成列表的一种式子嘛。其实列表生成式是快速生成一个列表的一些公式  ,比如当你需要生成一个1到50的所有偶数的列表,你会想我的天啊,这个好麻烦啊,不过你又仔细想了想不对,我学过for循环的嘛,于是,你忍不住写了下面的代码。

    1 a=[]
    2 for i in range(2,51,2):
    3     a.append(i)
    4 print(a)

    当你想跟你周围的女同学装逼的时候,我给你了一个眼神暗示,告诉你还有更装逼的方式。

    1 a=[i*2 for i in range(1,26)]
    2 print(a)

    在写列表生成式的时候,我看到还有一个叫列表生成器的骚操作,下面简单介绍一下两者的不同吧

    • 列表生成式: 会将所有的结果全部计算出来,把结果存放到内存中,如果列表中数据比较多,会占用过多的内存空间,可能导致MemoryError内存错误或者导致程序在运行时出现卡顿的情况 。
    •  列表生成器:会创建一个列表生成器对象,不会一次性的把所有结果都计算出来,如果需要序号获取数据,可以使用next()函数来获取,还可以使用 for循环遍历生成器对象,获取所有数据  

    卧槽,生成器又是什么东西,别急,下面就讲。

    三,迭代器和生成器

    1.生成器

    我们知道,列表里面的的数据是存在内存里面的,万一我需要存很多数据,那岂不是很占内存。而且有时候我们可能并不会用到里面的所有数据,可能只会用到一部分,这样就会造成极大的浪费。所以呢,我们就引入了一种叫生成器的东西。

    在 Python 中,使用了 yield 的函数被称为生成器(generator)。

    在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

    在生成器中,我们使用的是next()来查看下一个数据,当然我们也可以通过for循环来查看,因为生成器也是一个可迭代对象。

    下面是一个用生成器写的斐波那契数列

     1 #定义一个斐波那契函数
     2 def fbi(x):
     3     sum,a,b=0,0,1
     4     while sum<x:
     5         yield b
     6         a,b=b,a+b
     7         sum+=1
     8 a=fbi(3)
     9 
    10 #用next方法一条一条的取数据
    11 print(a.__next__()) #取出第一个数
    12 print(a.__next__())
    13 print(a.__next__())
    14 #如果当generator没有值你再继续调用next方法,会报一个StopIteration错误
    15 
    16 #用for循环读出里面的数据
    17 for i in a:
    18     print(i)
    View Code

    说到生成器,还有一种很厉害的用法,那就是生产者消费者模型,能够让人感觉在单线程下,实现事件的并发。如果想更好的理解流程,可以自己加上断点看清楚执行的流程。

     1 import time#导入time这个模块
     2 def buy(name):
     3     print('%s准备购买商品了'%(name))
     4     while True:
     5         number=yield #暂停并记住程序运行状态
     6         print('%s购买了%s商品'%(name,number))
     7 def protect():
     8     name=buy('zzq')#把生成器转化为一种地址
     9     name.__next__() #运行生成器,遇到yield就停止
    10     print('准备生产商品了')
    11     for i in range(5):
    12         time.sleep(2) #休眠两秒
    13         print('生产了%s的商品' %(i))
    14         name.send(i) #传值并运行
    15 protect()
    View Code

    流程的执行顺序是在函数protect中调用buy函数,这里只是把buy转化成了一个generator地址,然后在执行next函数的时候就执行buy函数,但是遇到yield的时候要停止,接着继续执行protect函数,到了send的时候,继续执行buy函数,并且把send里面的值,赋值给number。运行结果如下:

     1 zzq准备购买商品了
     2 准备生产商品了
     3 生产了0的商品
     4 zzq购买了0商品
     5 生产了1的商品
     6 zzq购买了1商品
     7 生产了2的商品
     8 zzq购买了2商品
     9 生产了3的商品
    10 zzq购买了3商品
    11 生产了4的商品
    12 zzq购买了4商品
    View Code

    2.迭代器

    在讲迭代器之前,必须了解的是可迭代对象。简单来讲,所有可以直接用for循环的对象都叫可迭代对象(Iterable)。哪些又能直接用呢,有下面两大类把。一类是集合类数据类型,比如一些列表(list),元组(tuple),字典(dict),字符串(str),集合(set),还有一类就是我们刚刚

    学到的genertor,包括生成器和带yield的generator function。

    可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

    四,装饰器

    在讲装饰器之前,吹吹小牛。李嘉诚说过一句话(好像是他讲的),其实我也没得什么特别的,只是我每天进步一点,然而我周围的人却停在了原地。学习也是一点一点积累起来的,差距也是一点一点拉开的。你坚持看到这里,会发现卧槽,原来装逼的在最后面。没错,前面我们讲的什么嵌套函数啊,高阶函数啊都是为今天的装饰器打下基础。

     装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的应用有插入日志、增加计时逻辑来检测性能、加入事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

    举一个简单的例子吧,比如现在有一个这样的需求,我现在想知道你每个函数运行的时间,不要问我为什么,我就是要你在每个函数加一个这样的功能,你心里此时估计一万句问候祖辈的话就来了。哈哈哈,有的人就想那我在每个函数里面加一个算运行时间的不就行了,但是我们写代码有两个要求吧,一个就是封闭性:已实现的功能代码块不应该被修改,还有一个就是可扩展性:对现有功能的扩展开放。你想了想我不管,我就是要在原来的函数上面加,但是我又告诉你一共有几百个函数,你当时就蒙了,卧槽,这该怎么玩呢。。。这是肯定用到装逼的装饰器了啥。其实装饰器就是在不改变函数的调用方式还有内部结构的基础上,然后再给函数增加其他功能。

    原来的函数

    1 import time
    2 def test():
    3     time.sleep(1)
    4     print('this is test')

    后面的代码或许会引起部分读者的不适,请谨慎读取。

     1 #计算函数花费时间
     2 def times(f): #后面引用函数的内存地址
     3     def internal(*args,**kwargs):
     4         stime=time.time()
     5         f(*args,**kwargs) #这里是相当于运行引用函数里面传有参数
     6         etime=time.time()
     7         print('cost time is %s' %(etime-stime))
     8     return internal
     9 
    10 import time
    11 @times #加在需要装饰的函数上面
    12 def test():
    13     time.sleep(1)
    14     print('this is test')
    15 test()
    16 
    17 #执行结果
    18 #this is test
    19 #cost time is 1.0007286071777344
    View Code

    装饰器具体的执行流程我在这里也不好具体介绍,也讲不太清楚,需要你自己去加断点一步一步去理解。所以。。。我也只能帮你到这里。但是这个装饰你又会想,装饰的这个函数没有返回值啊,如果有返回值应该怎么办呢。emmm,居然还是让你发现了,其实很简单,在原来的装饰器基础上加上一个返回值就行了。

     1 def times(f): #后面引用函数的内存地址
     2     def internal(*args,**kwargs):#这里是相当于运行引用函数里面传有参数
     3         stime=time.time()
     4         res=f(*args,**kwargs)#函数返回值赋值给res
     5         etime=time.time()
     6         print('cost time is %s' %(etime-stime))
     7         return res
     8     return internal
     9 
    10 import time
    11 @times #加在需要装饰的函数上面
    12 def test():
    13     time.sleep(1)
    14     print('this is test')
    15     return 'nb'
    16 print(test())
    17 #执行结果
    18 #this is test
    19 #cost time is 1.0007147789001465
    20 #nb
    View Code

    今天大概内容就这么多吧,后面就会讲今天提到的一些模块的具体用法。比如今天的time模块。我也是最近才开始写博客,前几天看到第一个人跟我评论然后关注我的时候心情那个激动啊,感觉自己很兴奋。最开始打算的是自己写了以后,第一相当于知识点回顾把,然后还有一个作用是忘记的知识可以跟翻笔记一样看看遗忘的知识点。现在发现居然有人看过我的博客,我很开心我这样的小白也能帮助到别人。最后我希望每个在追逐自己梦想的道路上,能够坚持走下去。

  • 相关阅读:
    iOS 代码让手机震动一下
    iOS开发 --制作圆形的头像(UIImage)
    JAVA基本数据类型和引用数据类型的区别
    jquery基础
    JS基础
    JAVA异常详解
    单例模式详解及java常用类
    JAVA基础之字符串和面向对象
    我的第一篇博客 初识动画,飞机行小动画
    GCD系列:调度组(dispatch_group)
  • 原文地址:https://www.cnblogs.com/zzqit/p/9179667.html
Copyright © 2020-2023  润新知