Python3编程
最爱喝酸奶
一直要努力!
展开
-
48. 在类中定义装饰器
要求:实现一个能将函数调用信息记录到日志的装饰器:把每次函数的调用时间、执行时间、调用次数写入日志;可以对被装饰函数分组,调用信息记录到不同日志;动态修改参数,比如日志格式;动态打开关闭日志输出功能。@call_info(arg1, arg2, arg3,...)def func(a, b): ...解决方案:为了让装饰器在使用上更加灵活,可以把类的实例方法作为装饰...原创 2020-02-18 18:38:48 · 1187 阅读 · 0 评论 -
47. 实现属性可修改的函数装饰器
在某项目中,程序运行效率较差,为分析程序内哪些函数执行时间开销较大,我们实现了一个带timeout参数的函数装饰器。装饰功能如下:@warn_timeout(1.5)def func(a,b): ...要求:统计被装饰函数单次调用运行时间;时间大于参数timeout的,将此次函数调用记录到log日志中;运行时可修稿timeout的值。解决方案:为包裹函数增...原创 2020-02-18 18:37:57 · 174 阅读 · 0 评论 -
46. 定义带参数的装饰器
要求:实现一个装饰器,它用来检查被装饰函数的参数类型。装饰器可以通过参数指明函数参数的类型,调用时如果检测出类型不匹配则抛出异常。@type_assert(str, int, int)def f(a, b, c): ... @type_assert(y=list)def g(x, y): ...解决方案:提取函数签名:inspect.signature()函数...原创 2020-02-14 19:50:02 · 316 阅读 · 0 评论 -
45. 为被装饰函数保存元数据
在函数对象中保存着一些函数的元数据,例如:__name__ 函数的名字__doc__ 函数文档字符串__module__ 函数所属模块名__dict__ 属性字典__default__ 默认参数元组...在使用装饰器后,再访问上面这些属性时,看到的是内部包裹函数的元数据,原来函数的元数据便丢失了。要求:为被装饰函数保存...原创 2020-02-14 19:49:11 · 184 阅读 · 0 评论 -
44. 使用函数装饰器
某些时候我们想问多个函数统一添加某种功能,比如计时统计、记录日志、缓存运算结果等等。我们不想在每个函数内添加完全相同的代码,如何更好的达成目的呢?要求:不在每个函数内添加完全相同的代码的前提下实现功能。解决方案:定义装饰器函数,用它生成一个在原函数基础上添加了新功能的函数,替代原函数。对于装饰器decorator:Python的装饰器decorator本质上是一个高阶函数,它接收一...原创 2020-02-14 19:48:20 · 287 阅读 · 0 评论 -
43. 使用多进程
由于Python中全局解释器锁(GIL)的存在,在任意时刻只允许一个线程在解释器中运行,因此Python的多线程不适合处理CPU密集型的任务。要求:想要处理CPU密集型的任务,可以使用多进程模型。解决方案:使用标准库中multiprocessing.Process类,它可以确定子进程执行任务。操作接口、进程间通信、进程加同步等都与threading.Thread类类似。对于multip...原创 2020-02-08 14:02:41 · 258 阅读 · 0 评论 -
42. 使用线程池
前面实现了一个多线程的web视频监控服务器,由于服务器资源有限(CPU,内存,带宽),需要对请求连接数(线程数)做限制,避免因资源耗尽而瘫痪。要求:使用线程池,替代原来的每次请求创建线程。解决方案:使用标准库汇总concurrent.futures下的ThreadPoolExecutor类,对象的submit()和map()方法可以用来启动线程池中的线程执行任务。对于ThreadPoo...原创 2020-02-08 14:02:14 · 281 阅读 · 0 评论 -
41. 使用线程本地数据
例如,我们实现了一个web视频监控服务器,服务器端采集摄像头数据,客户端使用浏览器通过http请求接收数据。服务器使用推送的方式(multipart/x-mixed-replace)一直使用一个tcp连接向客户端传递数据。这种方式将持续占用一个线程,导致单线程服务器无法处理多客户端请求。要求:改写程序,在每个线程中处理一个客户端请求,支持多客户端访问。解决方案:threading.local...原创 2020-02-04 10:38:40 · 480 阅读 · 0 评论 -
40. 在线程间进行事件通知
在之前通过使用多个DownloadThread线程进行下载(I/O)及使用一个ConvertThread线程进行转换(CPU),我们达到了多线程下载csv数据并转换为xml文件的目的。但现在有额外的要求:实现一个打包线程TarThread,将转换出的xml文件压缩打包。例如转换线程每生产出5个xml文件,就通知打包线程将它们打包成一个xxx.tgz文件,并删除xml文件。打包完成后,打包线程反过...原创 2020-02-04 10:37:01 · 284 阅读 · 0 评论 -
39. 线程间通信
前面我们已经通过多个线程下载csv数据并转换为xml文件。在Python中由于全局解释器锁(GIL)的存在,多线程进行CPU密集型操作并不能提高执行效率,我们修改程序框架:使用多个DownloadThread线程进行下载(I/O);使用一个ConvertThread线程进行转换(CPU);下载线程把下载数据安全地传递给转换线程。要求:实现上面的程序框架。解决方案:使用标...原创 2020-01-31 16:40:07 · 141 阅读 · 0 评论 -
38. 使用多线程
例如,我们通过 https://intrinio.com/tutorial/web_api 这个网址提供的api获取股市信息的csv数据,现在要下载大量csv数据文件,并将其转换为xml文件。要求:使用多线程来提高下载并处理的效率。解决方案:使用标准库threading.Thread类创建多个线程,在每个线程中下载并转换一只csv数据。对于threading.Thread类:cla...原创 2020-01-31 16:37:47 · 195 阅读 · 0 评论 -
37. 通过实例方法名字的字符串调用方法
某项目中,代码使用了三个不同库中的图形类:Circle,Triangle,Rectangle,它们都有一个获取图形面积的接口(方法),但方法名字不同。要求:实现一个统一的获取面积的函数,使用各种方法名进行尝试,调用相应类的接口。解决方案:使用内置函数getattr(),通过名字获取方法对象,然后调用。使用标准库operator下的methodcaller()函数调用。对于...原创 2020-01-26 15:02:39 · 209 阅读 · 0 评论 -
36. 在环状数据结构中管理内存
在Python中,垃圾回收器通过引用计数来回收垃圾对象。但某些环状数据结果(树、图、双向链表等),存在对象间的循环引用,比如树的父节点引用子节点,子节点同时也引用父节点。如果同时del掉引用父子节点,两个对象不能被立即回收。要求:解决此类的内存管理问题。解决方案:使用标准库weakref.ref类,它可以创建一种能访问对象但不增加引用计数的对象。对于wekref模块:class w...原创 2020-01-26 15:01:41 · 264 阅读 · 0 评论 -
35. 使用描述符对实例属性做类型检查
例如,在某项目中,我们实现了一些类,并希望能像静态类型语言(C,C++,Java)那样对它们的实例属性做类型检查。p = Person()p.name = 'Bob' #必须是strp.age = 18 #必须是intp.height = 1.83 #必须是float要求:1. 可对实例属性指定类型;2. 赋予...原创 2020-01-11 18:11:35 · 210 阅读 · 0 评论 -
34. 让类支持比较操作
有时我们希望自定义类的实例之间可以使用逻辑运算符进行比较,我们自定义比较的行为。例如,有一个矩形的类,比较两个矩形的实例时,比较的是它们的面积。class Rectangle: def __init__(self, w, h): self.w = w self.h = h def area(self): return se...原创 2020-01-11 18:10:14 · 206 阅读 · 0 评论 -
33. 创建可管理的对象属性
在面向对象编程中,我们把方法(函数)看作对象的接口。直接访问对象的属性可能是不安全的,或导致设计上不够灵活,但是使用调用方法在形式上不如访问属性简洁。例如:circle.get_radius() #调用方法circle.set_radius(5.0) #繁circle.radius #访问属性circle.re...原创 2020-01-11 18:09:26 · 197 阅读 · 0 评论 -
32. 让对象支持上下文管理
例如,实现了一个telnet客户端的类TelnetClient,调用实例的connect()、login()、interact()方法启动客户端与服务器交互,交互完毕后调用cleanup()方法关闭已连接的socket,以及将操作历史记录写入文件并关闭。要求:让TelnetClient的实例支持上下文管理协议,从而替代手动调用connect()、cleanup()方法。解决方案:实现上下文管...原创 2020-01-07 18:30:23 · 186 阅读 · 0 评论 -
31. 为创建大量实例节省内存
例如,在某网络游戏中,定义了玩家类Player(id, name, level, ...)。每有一个在线玩家,在服务器程序内则有一个Player的实例,当在线人数很多时,将产生大量实例(如百万级)。要求:降低大量实例的内存开销。解决方案:定义类的__slots__属性,声明实例有哪些属性(关闭动态绑定)。对于类的__slots__属性:>>> class Play...原创 2020-01-07 18:29:28 · 176 阅读 · 0 评论 -
30. 派生不可变类型
自定义一种新类型的元组,对于传入的可迭代对象,只保留其中int类型且值大于0的元素,例如:IntTuple([1, -1, 'abc', 6, ['x', 'y'], 3]) => (1, 6, 3)要求:继承内置tuple类实现IntTuple类。解决方案:继承内置tuple类,并实现__new__()方法,在其中修改实例化行为。对于类的实例化:在创建类的实例时,会在调...原创 2020-01-07 18:28:29 · 150 阅读 · 0 评论 -
29. 读写excel文件
Excel是日常办公中使用最频繁的软件之一,其数据格式为xls、xlsx,是一种非常常用的电子表格。例如:姓名 语文 数学 英语李雷 95 99 96韩梅 98 100 93张峰 94 95 95...要求:使用Python读写excel,添加“总分”列,计算每人总分。解决方案:使用第三...原创 2020-01-02 20:56:26 · 340 阅读 · 0 评论 -
28. 构建xml文档
有时,我们需要将其他格式数据转换为xml,例如把书籍信息csv文件转换成xml:books.csv: 书名, 作者, 出版社, 价格 精通scrapy网络爬虫, 刘硕, 清华大学出版社, 46.00 ...books.xml:<Data> <Book> <书名>精通scrapy网络爬虫</书名>...原创 2020-01-02 20:55:20 · 196 阅读 · 0 评论 -
27. 解析简单的xml文档
xml是极为常用的标记性语言,可以提供统一的方法来描述应用程序的结构化数据,例如demo.xml:<?xml version="1.0"?><data> <country name="Liechtenstein"> <rank>1</rank> <year>2008</year...原创 2019-12-21 13:35:59 · 217 阅读 · 0 评论 -
26. 读写json数据
在web应用中常用JSON(JavaScript Object Notation)格式传输数据,例如:利用http://httpbin.org/API对发送的http请求进行观测。爬虫程序利用Spalsh渲染引擎渲染页面。要求:在Python中读取json数据。解决方案:标准库中的json模块,使用其中loads()、dumps()方法完成json数据的读写。对于req...原创 2019-12-21 13:35:00 · 362 阅读 · 0 评论 -
25. 读写csv数据
例如,我们编写爬虫从豆瓣网爬取了一些书籍的信息,以csv数据格式存储:书名, 作者, 出版社, 价格精通scrapy网络爬虫, 刘硕, 清华大学出版社, 46.00算法导论, Charles E.Leiserson, 人民邮电出版社, 85.00Python灰帽子, Justin Seitz, 电子工业出版社, 39.00...要求:请将书价格高于80.00的书记录存储到另一csv文...原创 2019-12-21 13:33:47 · 346 阅读 · 0 评论 -
24. 使用临时文件
例如,在某项目中,我们从传感器采集数据,每收集到1G数据后,做数据分析,最终只保存分析结果。这样很大的临时文件如果常驻内存,将消耗大量内存资源。要求:使用临时文件存储这些临时数据(外部存储)。临时文件不用命名,且关闭后会自动被删除。解决方案:使用标准库中的TemporaryFile(临时文件)以及NamedTemporaryFile(命名临时文件)。对于TemporaryFile():...原创 2019-12-13 20:12:28 · 375 阅读 · 0 评论 -
23. 访问文件的状态
要求:在某些项目中,我们需要获得文件状态,例如:文件的类型(普通文件、目录、符号链接、设备文件…)。文件的访问权限。文件的最后的访问/修改/节点状态更改时间(即atime/mtime/ctime)。普通文件的大小。解决方案:系统调用:标准库os模块中的系统调用stat获取文件状态。快捷函数:标准库os.path下一些函数,使用起来更为简洁。对于...原创 2019-12-13 20:11:28 · 253 阅读 · 0 评论 -
22. 将文件映射到内存
要求:在访问某些二进制文件时,希望能把文件映射到内存中,可以像数组一样实现随机访问(例如linux的framebuffer设备文件)。某些嵌入式设备,寄存器被编址到内存地址空间,可以映射linux的/dev/mem某范围,去访问这些寄存器。如果多个进程同时映射同一个文件,还能实现进程通信的目的。解决方案:使用标准库中mmap.mmap()函数,将文件映射到进程的内存地址空...原创 2019-12-13 20:09:40 · 1062 阅读 · 0 评论 -
21. 设置文件的缓冲
将文件内容写入到硬件设备时,使用系统调用,这类I/O操作的时间很长。为了减少I/O操作的次数,文件通常使用缓冲区(有足够多的数据才进行系统调用)。文件的缓冲行为,分为全缓冲、行缓冲、无缓冲。要求:设置Python中文件对象的缓冲行为。解决方案:全缓冲:open函数的buffering参数设置为大于1的整数n,n即缓冲区大小。行缓冲:open函数的buffering参数设置为1。无缓冲:o...原创 2019-11-11 20:40:10 · 204 阅读 · 0 评论 -
20. 处理二进制文件
例如,wav是一种音频文件的格式,音频文件为二进制文件。wav文件由头部信息和音频采样数据构成。前面为头部信息,包括声道数、采样频率、编码位宽等,后面是音频采样数据。要求:使用Python,分析一个wav文件头部信息,处理音频数据。解决方案:通过内置函数open()指定mode参数为rb,以二进制模式读取二进制文件。解析二进制数据可以使用标准库中的struct.unpack()方法。...原创 2019-11-11 20:39:02 · 373 阅读 · 0 评论 -
19. 读写文本文件
在Python 2.x和Python 3.x中,字符串的语义发生了变化:Python2Python3strbytesunicodestr要求:某文本文件编码格式已知(如 UTF-8,GBK,BIG5),在Python 2.x和Python 3.x 中分别读写该文件。Python 2.x:写入文件前对unicode编码,读入文件后对字节进行解码。Python...原创 2019-11-11 20:38:27 · 169 阅读 · 0 评论 -
18. 在一个for循环中迭代多个可迭代对象
要求:(并行迭代)某班学生期末考试成绩语文、数学、英语分别存储在3个列表中,同时迭代3个列表,计算每个学生的总分。(串行迭代)某年级有4个班,某次考试每班英语成绩分别存储在4个列表中,依次迭代每个列表,统计全年级成绩高于90分人数。解决方案:(并行迭代)使用内置函数zip(),它可以将多个可迭代对象合并,每次迭代返回一个元组。(串行迭代)使用标准库中的itertool...原创 2019-10-05 11:57:00 · 581 阅读 · 0 评论 -
17. 对迭代器进行切片
例如, 有某个文本文件,想读取其中某范围的内容,如100 ~ 300行之间的内容,python中文件是可迭代对象。要求:使用类似列表切片的方式得到一个100 ~ 300行文件内容的生成器。解决方案:使用itertools.islice()函数,它能返回一个迭代对象切片的生成器。对于列表切片:>>> l = list(range(10))>>>...原创 2019-10-05 11:54:52 · 204 阅读 · 0 评论 -
16. 实现正、反向迭代
要求:实现一个连续浮点数发生器FloatRange(和range类似),根据给定范围(start, end)和步长(step)产生一系列连续浮点数。如迭代FloatRange(3.0, 4.0, 0.2)可产生序列:正向:3.0 → 3.2 → 3.4 → 3.6 → 3.8 → 4.0反向:4.0 → 3.8 → 3.6 → 3.4 → 3.2 → 3.0解决方案:实现反向迭代协议的...原创 2019-10-01 12:56:16 · 289 阅读 · 0 评论 -
15. 使用生成器函数实现可迭代对象
要求:实现一个可迭代对象的类,它能迭代出给定范围内的所有素数(只能被1和自己整除的数,2除外):pn = PrimeNumbers(1, 30)for k in pn: print(k)输出结果:2 3 5 7 11 13 17 19 23 29解决方案:将该类的__iter__()方法实现为生成器函数,每次yield返回一个素数。对于生成器函数:在Python...原创 2019-10-01 12:55:05 · 438 阅读 · 0 评论 -
14. 实现可迭代对象和迭代器对象
例如,某天气软件要求,通过网络抓取各个城市气温信息,并依次显示:北京:15 ~ 20天津:17 ~ 22长春:12 ~ 18...如果一次抓取所有城市气温信息再显示,显示第一个城市气温时,有很高的延时,并且浪费存储空间。要求:以“用时访问”的策略,并将所有城市气温信息封装到一个对象里,可用for循环进行迭代。解决方案:Step1:实现一个迭代器对象WeatherIterator,...原创 2019-10-01 12:53:49 · 218 阅读 · 0 评论 -
13. 去除字符串中不需要的字符
要求:过滤掉用户输入中前后多余的空白字符:' nick2008@gmail.com '过滤Windows下编辑文本中的\r、\n:'hello world\r\n'去掉文本中的Unicode组合符号(音调):'nǐ hǎo,shì jiè'解决方案:字符串的strip()、lstrip()、rstrip()方法去掉字符串两端的字符;删除单个固定位置的...原创 2019-09-24 21:23:39 · 1409 阅读 · 0 评论 -
12. 对字符串进行左、右、居中对齐
例如,某字典存储了一系列属性值:{ "lodDist": 100.0, "SmallCull": 0.04, "DostCull": 500.0, "trilinear": 40, "farclip": 477}要求:在程序中,以key的最大长度对齐,格式工整地将其内容输出:lodDist : 100.0SmallCull : 0.04Do...原创 2019-09-24 21:22:17 · 943 阅读 · 0 评论 -
11. 将多个小字符串拼接成一个大字符串
例如,在设计某网络程序时,自定义了一个基于UDP的网络协议,按照固定次序向服务器传递一系列参数:hwDetect: "<0112>"gxDepthBits: "<32>"gxResolution: "<1024x768>"gxRefresh: "<60>"fullAlpha: "<1>"...原创 2019-09-20 15:52:39 · 736 阅读 · 0 评论 -
10. 调整字符串中文本的格式
例如,某软件的log文件中的日期格式为yyyy-mm-dd:2019-05-21 10:39:26 status unpacked python3-pip:all2019-05-23 10:49:26 status half-configured python32019-05-23 10:52:26 status installed python3-pip:all2019-05-24 11...原创 2019-09-20 15:51:03 · 206 阅读 · 0 评论 -
9. 判断字符串是否以另一字符串开头或结尾
例如,某文件系统目录下有一系列文件:quicksort.cgraph.pyheap.javainstall.shstack.app要求:给其中所有的.sh和.py文件加上用户可执行权限。解决方案:使用字符串的startswith()和endswith()方法,多个匹配时参数使用元组。对于字符串的startswith()和endswith()方法:字符串的startswi...原创 2019-09-20 15:49:30 · 1526 阅读 · 0 评论