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

可以使用isinstance()判断一个对象是否是Iterator对象。一个是iterable,一个是iterator。

list,tuple,dict这些是iterable,但不是iterator,这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

但是iterable是可以通过iter()变成iterator对象的,而python里面的for循环实质上就是一个iterator一直next的过程。

函数式编程

map/reduce

比如有一个iterable, 想要把这个iterable里面的所有元素都乘上两倍,当然可以使用for循环一个一个处理,但是用map就可以一起做:

会把iterable的元素一个一个的取出来作用在f函数上面。map之后返回的是一个iterator,是一个惰性的数组,所以是需要用list来转变一下。再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

上面的一个例子看起来是毫无作用,对于字符串转数字的的问题其实是很适用的:

利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:['adam', 'LISA', 'barT'],输出:['Adam', 'Lisa', 'Bart']:

Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积:

利用map和reduce编写一个str2float函数,把字符串'123.456'转换成浮点数123.456:

filter

filter是一个过滤器,它的主要用法和map差不多的,只不过它要求的函数是返回True or False,返回True的留下,False的离开。

计算素数的一个方法是埃氏筛法,它的算法理解起来非常简单:

首先,列出从2开始的所有自然数,构造一个序列:

2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取序列的第一个数2,它一定是素数,然后用2把序列的2的倍数筛掉:

3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取新序列的第一个数3,它一定是素数,然后用3把序列的3的倍数筛掉:

5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取新序列的第一个数5,然后用5把序列的5的倍数筛掉:

7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

不断筛下去,就可以得到所有的素数。

not_divisible这个函数返回的就是一个函数,lambda的匿名函数,使用filter过滤即可。

回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数:

sorted

看名字就知道是排序算法了。

sorted是一个高阶函数,可以接收一个key来自定义排序的方式:

也可以用于对字符串的排序

由于

的ASCII码是大于

的,所以自然就是在后面,如果想不区分排序,可以全部转成小写再排。

假设我们用一组tuple表示学生名字和成绩:

L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

请用sorted()对上述列表分别按名字和成绩排序:

返回函数

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

比如想计算一些数字的和,但是并不想立刻就知道,这个时候就可以返回一个函数了:

等到调用了f函数的时候才会进行计算,调用lazy_sum的时候会保留一些结果。

事实上如果是在传入一个一模一样的参数得到结果也还是一样的。但是这得到的这两个返回函数是两个不一样的返回函数:

两个函数指向的地址不是一样的。

这种返回函数的方法叫做闭包:

这个时候返回的其实是三个9,因为他们全部都是引用了i,而这个函数返回是等到循环执行完才会返回的,所以到循环执行完这个i就是3了,所以就是三个9。所以这如果要使用闭包,返回函数不要引用任何循环变量,或者后续会发生变化的变量。

如果要正常的输出

,需要改成这样:

匿名函数

其实就是lambda表达式,如果是求一个列表的平方,那么要写一个函数,然后map即可。如果是lambda匿名函数就会间断点:

装饰器

由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。本质上,装饰器就是一个返回函数的一个高阶函数。

现在有一个输出当前时间的函数:

如果你还想知道输出的这个函数的名字是什么,但是又不行改变这个函数本身,那么就可以使用装饰器了。

其实就是相当于log(now)

请设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间:

偏函数

Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。在介绍函数参数的时候,我们讲到,通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。比如:int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:

functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

面向对象

类和实例

这样就定义了一个类,object代表的是从哪一个类继承的。

这个时候bart就指向一个student类的,后面的一串十六进制其实就是这个对象的地址。可以把student当成是一个模板,有什么必要的属性可以先丢进去,可以同过一个init函数把这些必要的属性先固定好。而如果对象再绑定属性那么这时候这个属性就仅仅是属于这个对象的了。

这个name就是仅仅绑定在了bart这个对象上面。

这个时候name和score就绑定在了类上面,创造的每一个对象都会存在这两个属性。

访问限制

上面所定义的变量都是公有变量,如果需要访问限制,那就是私有变量了。

如果要访问,那么就可以使用内部函数来访问:

事实上python的私有变量并不是严格意义上的私有变量,在外部是可以访问的,类名_属性名是可以访问的:

使用只能靠自觉了。

要注意一种错误写法,bart.__name = 'srgr',这样是不可以访问私有变量的,只会增加一个叫__name的新公有变量而已。

继承和多态

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类。比如有一个动物类:

继承了animal类之后它方法也顺次继承了下来。

也可以加上属性和函数,覆盖原来的基类方法。

当我们定义了一个class类的时候实际上定义了一个数据类型:

但是如果反着来:

小的可以往大的转,大的不能往小的转。Dog可以看成Animal,但Animal不可以看成Dog。

你会发现,新增一个Animal的子类,不必对run_twice()做任何修改,实际上,任何依赖Animal作为参数的函数或者方法都可以不加修改地正常运行,原因就在于多态。多态的好处就是,当我们需要传入Dog、Cat、Tortoise……时,我们只需要接收Animal类型就可以了,因为Dog、Cat、Tortoise……都是Animal类型,然后,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此,传入的任意类型,只要是Animal类或者子类,就会自动调用实际类型的run()方法,这就是多态的意思。对于一个变量,我们只需要知道它是Animal类型,无需确切地知道它的子类型,就可以放心地调用run()方法,而具体调用的run()方法是作用在Animal、Dog、Cat还是Tortoise对象上,由运行时该对象的确切类型决定,这就是多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。

对外扩张:可以添加animal子类。

对内封闭:不需要修改和基类有关的函数。

获取对象信息

首先判断一个数据类型可以使用

函数,基本类型都可以用

来判断。

对于函数和类都可以使用这个

函数判定:

如果是直接判断类型,是可以直接写int和str,但是如果判断函数,就需要用到

了。

instance函数。isinstance()就可以告诉我们,一个对象是否是某种类型。

isinstance()判断的是一个对象是否是该类型本身,或者位于该类型的父继承链上。

可以判断有没有这个属性:

由于Python是动态语言,根据类创建的实例可以任意绑定属性。给实例绑定属性的方法是通过实例变量,或者通过self变量:

这个时候的属性是绑定在了实例变量上,如果这个属性是属于这个类的,就可以直接定义:

千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

使用slots

如果想做这个类里面新添加一个方法的话那就要用到MethodType方法:

如果想要限制属性的添加,那就可以用slots方法了。

slots只是对当前的类有效果,如果要想对子类有效果,那么就要重新设置一个,这个时候子类的就等于父类的加上子类的限制了。

使用property

每一个都这样设置,烦死了,而@property就是一个把方法调用变成属性的一个装饰器:

单单设置了property就是只读而已,如果要是写,那么就要setter方法,这样非常安全。

由于resolution只是设置了property,使用只是只读而已。对于上面其他的属性设置了property和setter使用可读可写了。

多重继承

我们想要实现下列的一些动物,需要用到多重继承:

在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为MixIn。

这样一来就不再需要庞大的继承链了,只需要组合一些类的继承就好了。

定制类

这样输出感觉有点不好看,可以用str函数定制一下输出效果:

设置了str打印类信息是按照自定义格式,但是如果是对象就不是了。

如果要自定义类的效果,那就必须要设置repr == str:

如果一个类想被用于for ... in循环,类似list或tuple那样,就必须实现一个iter()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。我们以斐波那契数列为例,写一个Fib类,可以作用于for循环:

定义一个iter把这个类转变成一个迭代器,再定义一个next迭代输出。

上面的设计虽然可以变成一个迭代器,但是是不可以按照list的类型来取的,比如[]等等。

同时,如果定义了call函数,是可以直接对实例进行调用的。

枚举类

当我们需要定义常量的时候,一个方法是用大写的变量来定义:

麻烦,可以直接使用枚举类来解决:

自动会从1开始计时:

如果需要更加准确的定义一个枚举类:

使用元类

之前讨论过type函数,type()函数既可以返回一个对象的类型,又可以创建出新的类型,比如,我们可以通过type()函数创建出Hello类,而无需通过class Hello(object)...的定义:

type需要三个参数,类名,基础的基类,由于继承的基类可以不止是一个,使用要注意元祖的格式,通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。正常情况下,我们都用class Xxx...来定义类,但是,type()函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。

错误,调试和测试

错误处理

之前一般用来抛出错误的都是使用错误码,但是错误码表示错误其实行麻烦的,使用一般的语言都会内置try...catch机制,python也不例外。

改一下:

使用try...except捕获错误还有一个巨大的好处,就是可以跨越多层调用,比如函数main()调用foo(),foo()调用bar(),结果bar()出错了,这时,只要main()捕获到了,就可以处理:

如果错误没有被捕获,它就会一直往上抛,最后被Python解释器捕获,打印一个错误信息,然后程序退出:

如果不捕捉,那么错误就会一直往上抛,抛到最顶为止。如果不捕获错误,自然可以让Python解释器来打印出错误堆栈,但程序也被结束了。既然我们能捕获错误,就可以把错误堆栈打印出来,然后分析错误原因,同时,让程序继续执行下去。

可以使用logging模块:

logging相当于一个日志,把错误都记录下来,然后继续执行下面的,执行完了再把错误抛出来。

因为错误是class,捕获一个错误就是捕获到该class的一个实例。因此,错误并不是凭空产生的,而是有意创建并抛出的。Python的内置函数会抛出很多类型的错误,我们自己编写的函数也可以抛出错误。如果要抛出错误,首先根据需要,可以定义一个错误的class,选择好继承关系,然后,用raise语句抛出一个错误的实例:

捕获错误目的只是记录一下,便于后续追踪。但是,由于当前函数不知道应该怎么处理该错误,所以,最恰当的方式是继续往上抛,让顶层调用者去处理。好比一个员工处理不了一个问题时,就把问题抛给他的老板,如果他的老板也处理不了,就一直往上抛,最终会抛给CEO去处理。raise语句如果不带参数,就会把当前错误原样抛出。此外,在except中raise一个Error,还可以把一种类型的错误转化成另一种类型:

单元测试

写完一个类或者是功能我们需要做一些测试,比如我们想要:

实现的这个类想要和python的数据类型dict实现的效果一样。为了做单元测试,需要实现也单元测试的类:

以test开头的方法就是测试方法,不以test开头的方法不被认为是测试方法,测试的时候不会被执行。对每一类测试都需要编写一个test_xxx()方法。由于unittest.TestCase提供了很多内置的条件判断,我们只需要调用这些方法就可以断言输出是否是我们所期望的。最常用的断言就是assertEqual()。写完之后就可以运行单元测试了:

对于单元测试还有两个方法:setup()和setdown()。分别是在调用测试方法前后执行,假设你有数据库,那么就可以在setup打开,setdown关闭啦。

对Student类编写单元测试,结果发现测试不通过,请修改Student类,让测试通过:

IO操作

文件读写

读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

打开一个文件对象,使用的就是open()这个函数,传入打开的文件位置和参数。

如果文件不存在,它会抛出一个IOerror的错误:

python123动物重量排序_python基本常识相关推荐

  1. python123动物重量排序_Python爬虫图片学习(一)

    Python爬虫学习 一.Python安装与调用 python官网安装地址:https://www.python.org/ python帮助手册:在本机的路径C:\Users\Administrato ...

  2. python123动物重量排序_python进阶

    面向对象oopclass Student(object): def __init__(self,name,score) self.name = name self.score = score def ...

  3. python123动物重量排序_Python二级真题共12组前6组多项选择题,python,十二,套前,六套...

    下半部分 --> 请点击 https://blog.csdn.net/ExclusiveName/article/details/104537908 第一套试题 关于数据的存储结构,以下选项描述 ...

  4. python动物重量排序_python动物重量排序_Python小白干货宝典:sorted()函数:列表元素排序...

    定义: sorted() 函数对所有可迭代的对象进行排序操作. 内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作. 语法: sorted 语法: sorted(i ...

  5. python123动物重量排序_Python3学习–列表

    释放双眼,带上耳机,听听看~! 列表:用于存储任意数目.任意类型的数据集合. 列表是内置可变序列,是包含多个元素的有序连续的内存空间.列表定义的标准语法格式: a = [10,20,30,40] 其中 ...

  6. python动物重量排序详解

    先看题目: 输入格式‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬ 每次输入一个动物名,以及其重量和单位,动物名与重量 ...

  7. python动物重量排序_动物分类的Sklearn模型

    编辑: 所以我设法用所有的建议来修正错误.但是现在模型.预测部分是给我这个问题.在Expected 2D array, got 1D array instead: array=[ 12 15432 4 ...

  8. python动物重量排序_动物英语单词按字母排列

    动物 Ant 蚂蚁 alligator 短吻鳄 ass 笨驴 albatross 信天翁 alpaca 羊驼 anchovy 凤 尾鱼 anteater 大食蚁兽 antilope 羚羊 armadi ...

  9. python动物重量排序_用python画简单的动物代码

    用python画简单的动物代码 发布时间:2020-04-30 14:57:42 来源:亿速云 阅读:344 作者:小新 今天小编给大家分享的是用python画简单的动物代码,相信很多人都不太了解,为 ...

最新文章

  1. minui 向div放html,c# – 如何添加css类到html通用控件div?
  2. DButils数据库升级不丢失数据
  3. MySQL存储引擎InnoDB,MyISAM
  4. 傲腾明年爆发 Intel霸占企业市场,成SSD真正赢家
  5. Spring框架(下)JdbcTemplate、声明式事务管理
  6. Nginx配置——禁止指定user_agent
  7. JSTL 核心标签库 使用(C标签)
  8. mysql函数变量存储_MySQL存储过程、存储函数、变量
  9. socket php建立聊天室,PHP搭建socket聊天室
  10. 光盘文件格式-udf、iso9660、Joliet、Romeo
  11. MySQL 名次查询
  12. 『python思考』关于列表的浅复制和深复制的理解
  13. stm32 hid 双向通信
  14. 电脑组成部件介绍图解:电脑的硬件组成部分及其作用各是什么?
  15. 《重构:改善既有代码的设计》读书笔记(下)
  16. 软件网关工业生产设备PLC数据采集转存数据库记录仪IOT gateway
  17. 软件测试工程师需要什么软件_为什么每个软件工程师都应该撰写文章
  18. 基于Linux系统的GTK+图形界面编程——扫雷游戏
  19. 冰蝎无法打开(Behinder无法运行)
  20. AI如何影响智能交互

热门文章

  1. python 排序 sorted 如果第一个条件 相同 则按第二个条件排序
  2. 机器学习算法之决策树
  3. opencv与两个摄像头实现双目标定与测距
  4. git搭建局域网服务器
  5. oracle递归用法
  6. 25 进程同步之Event
  7. Cissp-【第3章 安全工程】-2021-2-23(290页-321页)
  8. 如何用python数据挖掘_Python数据挖掘-文本挖掘
  9. volatile和内存屏障(dmb)
  10. linux下lua bit模块的安装