Python核心技术与实战——四|Python黑箱:输入与输出

时间:2023-03-10 07:11:23
Python核心技术与实战——四|Python黑箱:输入与输出

抽象的看,Python程序可以被看成一个黑箱:通过输入流将数据送达,经过处理后在输入,也就是说具备了一个图灵机运作的必要条件。

输入输出基础

最简单的输入是来自键盘的操作

name = input('please input your name:')
print('welcome {}!'.format(name))

程序运行到input处会暂停运行,同时等待键盘的输入直到回车被按下。函数的参数就是提示语,输入的数据类型永远都是字符串型。这里就要注意在使用时的容错处理

name = input('please input your name:')
age = input('please input your age:')
age = int(age)
print('welcome {}!'.format(name))

在这里由于进行了一个强制转换,如果输入的数据不是数字类型的字符串的话程序就会报错

please input your name:aa
please input your age:a
Traceback (most recent call last):
File "D:/python/PyQt_GUI/QDialog/color.py", line 140, in <module>
age = int(age)
ValueError: invalid literal for int() with base 10: 'a'

所以在使用时一定要注意到这种情况,加上try except。

try :
age = int(age)
except ValueError as e:
print('age should be int')

还有一个要注意的点:Python对int类型是没有最大限制的(相对C++来说int最大值为2147483647,超出会产生数据溢出)。

文件输入输出

  命令行的输入输出只是提供了Python交互的最基本的方式,而生产级的I/O大部分来自文件、网络或其他进程的消息。下面我们就详细的分析一个文本文件的读写,假设有个文本文件in.txt,内容是下面的

 I have a dream that my four little children will one day live in a nation where not bejudged by the color of their skin but the content of their character.I have a dream today.

 I have a dream that one day down in Alabama,with its vicious racists, . . . one day right there in Alabama little black boys and girls will be able to join hands with little white boys and girls as sisters and brothers.I have a dream today.

 I have a dream thatone dya every valley shall be exalted,every hill and mountain shall be made low,the rough places will be made plain,and the crooked places will be made straight, and the glory of the Lord shall be revealed, and all flesh shall see it together.

 This is our hope. . .With this faith we will be able to hew out of the mountain of despair a stone of hope.With this faith we will be able to transform the jangling discords of our nation into a beautiful symphony of brotherhood. With this faith we will be able to work together,l to pray together,to struggle together, to go to jail together, to stand up for freedom together, knowing that we will be free one day. . .

 And when this happens, and when we allow freedom ring, when we let it ring from every village and evety hamlet, from every state and every city, we will be able to speed up that day when all of God's children, black men and white man, Jews and Gentiles, Protestants and Catholics, will be anle to join hands and sing in the words of the old Negro spiritual: "Free at last! Free at last! Thank God Almighty, we are free at last!"

  然后来做一个最简单的NLP(自然语言处理),NLP任务的基本步骤分成下面几步

  1.读取文件;

  2.出去所有标点符号和换行符,把所有大写变成小写;

  3.合并相同的词,统计每个词出现的频率,并按词频从大到小排序;

  4.将结果按行输出到文件out.txt

  然后我们来看一看下面的代码

import re
def parse(text):
#除去标点和换行符
text = re.sub(r'[^\w]',' ',text)
#转换为小写
text = text.lower()
word_list = text.split(' ')
#统计词频
word_cnt = {}
for word in word_list:
if len(word)!=0:
if word in word_cnt:
word_cnt[word]+=1
else:
word_cnt[word] = 1
#字典重新排序
replace_word = sorted(word_cnt.items(),key=lambda kv:kv[1],reverse=True)
return replace_word with open('in.txt','r') as f:
text = f.read()
word_freq = parse(text) with open('out.txt','w') as f:
for word,freq in word_freq:
f.write("{}:{}\n".format(word,freq))

我们先用open()函数拿到文件的指针,然后通过read()函数读取文件的内容到内存中,并赋值给变量text。然后调用parse函数进行分析。这种方式的优点是方便,可以直接在内存中进行分析,当然缺点是如果文件过大,一次性读取就可能造成内存崩溃。

  这时候我们可以给read()指定个size,用来表示每次读取的最大长度,或者用readline()函数每次只读取一行。这种做法常用于数据挖掘(Data Mining)中的数据清洗。如果每行之间没有关系也可以降低内存的压力。(在Python之ftp服务器中put或get文件时就是用的这种方法)。但是在上面NLP的案例中由于存在单词被截断的问题,是不能用的。这留下作为一个思考题后面再讲。

  在打开文件的时候用的是with语句。因为open()函数对应了close()函数,也就是说打开文件完成读取任务后应该立刻关掉它。而如果使用了with语句就不需要显示的调用close()。在with的段落下任务执行完毕后close()会自动被调用,代码也简洁的多。

  这里要插播两点要注意的地方:

    1.在用open()函数时一定要注意权限的设定,如果是读取权限就不要请求权限,可以试一下把权限改成

with open('in.txt','w+') as f:
text = f.read()
word_freq = parse(text)

执行前一定要注意备份in.txt文件!执行前一定要注意备份in.txt文件!执行前一定要注意备份in.txt文件!

执行的以后可以发现原文件成空的了~只能准备跑路了!

    2.在进行文件I/O的时候要记得进行异常处理。因为I/O操作可能会由各种各样的情况出现,而一个健壮(robust)的程序应该能应对各种情况的发生而不会崩溃。

三.JSON序列化

  JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,他的设计意图是把所有的事情都用字符串来表示,作为两种不同语言之间的”黑箱“

  1.把各种杂七杂八的信息序列化,输出一个字符串

  2.输入一个字符串,输出一个包含原始信息的字典。

  Python的Json序列化里讲了Json的基本使用方法,这里就不再多说了!不过还是那句话,记得加上异常处理,不然即便是给json.loads()发送了一个非法字符串程序就会崩溃了!

  除了JSON序列化,还有多种选择Google开源了它的类似的工具(Protocol Buffer),可以了解一下!相比于JSON,他的有点是生成优化后的二进制序列。在TensorFlow等对性能有要求的系统中有广泛的应用。

四.思考题

  1.考虑一下上面一节说的在对比较大的文件进行I/O时怎么分段读取而不破坏单词的完整性。

  2.加试题:我们把家里一个100G的数据通过网盘传递给公司的电脑,每次从家里的电脑通过server.py向网盘写5G的数据,公司的client.py一旦侦测到有新的数据就get文件到本地,完成操作后删除网盘上的数据,家里的电脑检测到数据成功被get后重新put下一个文件。