《对廖雪峰老师的Python教程的学习小结四》

下面是第四部分的内容。内容中涉及的程序均来源于廖老师的Python教程(网址为https://www.liaoxuefeng.com/wiki/1016959663602400/)。

十、IO编程

IO:Input、Output。

Input:数据从外面流入到内存中;Output:数据从内存流入到外面。

例如:你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作叫Output,随后新浪服务器把网页发过来,这个动作叫Input。

由于CPU和内存的运算速度比外设的快,所以存在速度不匹配的问题。对此,有同步IO和异步IO两种方式。操作IO的能力是由操作系统决定的,在本章节介绍的是同步IO的方式

1. 文件读写

(1)读

with open('/path/to/file', 'r') as f:

    print(f.read())

read是一次性读入所有的文件,可以用read(size)来限定读入的文件的大小。按行读取文件中的内容,可以使用readlines,如下所示:

for line in f.readlines():

    print(line.strip()) # 把末尾的'\n'删掉

上述介绍的是读取UTF-8编码的文本文件。如果按照二进制读取视频、图片这样的文件的话,可以按照下面的方式读取:

>>> f = open('/Users/michael/test.jpg', 'rb')

>>> f.read()b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节

如果要读取非UTF-8的文本文件,可以传入encoding参数,如读取GBK编码的文件,有

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')

>>> f.read()

'测试'

对于有编码错误的文件,可以将错误忽略,如下

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')

f.close()会关闭文件。

(2)写

with open('/Users/michael/test.txt', 'w') as f:

    f.write('Hello, world!')

将上述的w换为wb表示以二进制的形式写入文件。

写入特定编码的文本文件,请给open()函数传入encoding参数,将字符串自动转换成指定编码。

以'w'模式写入文件时,如果文件已存在,会直接覆盖(相当于删掉后新写入一个文件)。若希望追加到文件末尾,可以传入'a'以追加(append)模式写入。

2. StringIO和BytesIO

第1小结是在文件中读写,对于在内存中的读写则可以使用StringIO和BytesIO。前者表示读写str,后者表示读写二进制数据。

3. 操作文件和目录

在Python中执行对操作系统的文件、目录的操作,可以使用os模块或os.path模块下的函数。

4. 序列化

自己不是很理解教程中讲解引入序列化的必要性。

十一、进程和线程

对于操作系统而言,一个任务就是一个进程。一个进程至少有一个线程。

执行多任务的形式:多进程模式;

                                多线程模式;

                                多进程+多线程模式。

线程是最小的执行单元。如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间。

Python既支持多进程,又支持多线程。

1. 多进程

(1)Python的fork()

Unix/Linux提供fork()系统调用,相比于普通的函数调用,调用一次fork()操作系统会返回两次。因为,操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后分别在父进程和子进程内返回。对于常见的Apache服务器就是由父进程监听端口,当有http请求到来时,就fork出子进程发来响应http请求。

Python的os模块封装了常见的系统调用,其中包括fork()。子进程调用getppid()可以得到父进程的ID。子进程永远返回0,父进程返回子进程的ID。

(2)Python的multiprocessing

Windows中不支持fork,那么在Windows中就无法实现Python中的fork()调用了。但是,Python是可以实现跨平台的多进程的,可以使用multiprocessing模块,该模块提供了一个Process类来代表一个进程对象。

父进程所有Python对象都必须通过pickle序列化再传到子进程去,所有,如果multiprocessing在Windows下调用失败了,要先考虑是不是pickle失败。

(3)进程池pool(xxx)

可以使用进程池的方式来实现批量创建子进程。pool(xxx)中的数字xxx不是由操作系统决定的,默认值表示CPU的数目,xxx表示子进程的数目。

(4)子进程      自己不是很明白其中的例子

subprocess模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。

(5)进程之间的通信

是通过Python中的multiprocessing中的Queue、Pipes等实现的。

2. 多线程

除了1中可以用多进程来完成多任务,也可以通过一个进程中的多线程来实现。Python的线程是真正的Posix Thread,而不是模拟出来的线程。

(1)Threading

Python的标准库中提供了threading模块。模块中的current_thread()函数会返回当前线程的实例。任何进程都会默认返回一个进程,这个线程被称为“主线程”,主线程又会启动新的线程—子线程。主线程的实例名字是MainThread,子线程的实例名字是自己设置的。

(2)Lock(锁)

进程:同一个变量在各进程中均有一份拷贝,彼此之间互不影响;

线程:所有变量都由线程共享,因而存在多个线程修改同一个变量,导致变量被修改。

因而,可以设一个锁,只有当获得锁的进程的锁被释放(若没有释放,会出现死进程,可以用try...finally来确保锁一定被释放)后,下一个进程才能进行操作。这也导致了锁的坏处:(1)无法并行执行多任务,使得变成了单进程;(2)由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也无法结束,只能靠操作系统强制终止。

(3)多核下的多线程

Python下无法实现多核的多线程,因而无法实现多线程的并发。即使100个线程跑在100核CPU上,也只能用到1个核,这与Python解释器是有关的(详见廖老师的教程)。但是,可以实现多核的多进程。

3. ThreadLocal

由2可知,多线程中变量是共享的,所以必须加锁,这在一些方面会带来不好的结果。因而,对于每个线程来说,最好使用局部变量。为了更好地实现,引入ThreadLocal变量。

虽然ThreadLocal变量是是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。

4. 进程 vs 线程

(1)对比

为了实现多任务,我们会设计出Master-Worker模式。Master负责分配任务,Worker负责执行任务。在进程中,主进程是Master,其它进程是Worker。在线程中,主线程是Master,其它线程是Worker。下面对比下进程和线程,有

进程:优点:稳定性高(一个子进程崩溃了不会影响其它进程,主进程崩溃的可能性比较小);缺点:收到CPU和内存的限制,创建进程的代价比较高。

线程:优点:执行速度比进程稍快些。

           缺点:所有线程共享进程的内存。当任意一个进程崩溃时,其余进程也会崩溃。

Apache服务器是多进程的模式。微软的ISS服务器是多线程模式。综合线程和进程的优缺点,又有了多进程+多线程的混合模式。

(2)分析

无论是多进程还是多线程,当处理多任务时,由于要频繁地切换。所以会导致效率的下降。所以,任务量不宜过多。

我们可以根据执行任务所需的CPU计算资源,将任务划分为:计算密集型和IO密集型。前者主要消耗CPU资源,后者消耗较少的CPU资源。对于前者,采用C语言(运行效率较高)处理任务;对于后者,采用脚本语言处理较好(脚本语言的代码量比较少,运行效率较低,但是影响不大)。实际上,大多数的任务是IO密集型的,可以利用操作系统所支持的异步IO来实现多任务。

5. 分布式进程

结合4的(1),在实现分布式运算中,应该优先选择多进程。因为,比较稳定,而且可以分布到多台机器上。对于,多线程则只能分布到一台机器的多个CPU上。

Python的multiprocessing模块的managers支持将多进程分布到多机器上。Python的分布式进程接口简单,对于每个任务所处理的数据量应该尽量少!

分布式进程的具体代码实现见教程。

十二、正则表达式

Python提供re模块,包含所有正则表达式的功能。

教程中给出了一些例子,可以自己理解和进行实现。

正则表达式的功能是很强大的,如果需要用到正则表达式的话可以买一本参考书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值