Python核心技术与实战
景霄
Facebook资深工程师
立即订阅
13891 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 从工程的角度深入理解Python
免费
基础篇 (14讲)
01 | 如何逐步突破,成为Python高手?
02 | Jupyter Notebook为什么是现代Python的必学技术?
03 | 列表和元组,到底用哪一个?
04 | 字典、集合,你真的了解吗?
05 | 深入浅出字符串
06 | Python “黑箱”:输入与输出
07 | 修炼基本功:条件与循环
08 | 异常处理:如何提高程序的稳定性?
09 | 不可或缺的自定义函数
10 | 简约不简单的匿名函数
11 | 面向对象(上):从生活中的类比说起
12 | 面向对象(下):如何实现一个搜索引擎?
13 | 搭建积木:Python 模块化
14 | 答疑(一):列表和元组的内部实现是怎样的?
进阶篇 (11讲)
15 | Python对象的比较、拷贝
16 | 值传递,引用传递or其他,Python里参数是如何传递的?
17 | 强大的装饰器
18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?
19 | 深入理解迭代器和生成器
20 | 揭秘 Python 协程
21 | Python并发编程之Futures
22 | 并发编程之Asyncio
23 | 你真的懂Python GIL(全局解释器锁)吗?
24 | 带你解析 Python 垃圾回收机制
25 | 答疑(二):GIL与多线程是什么关系呢?
规范篇 (7讲)
26 | 活都来不及干了,还有空注意代码风格?!
27 | 学会合理分解代码,提高代码可读性
28 | 如何合理利用assert?
29 | 巧用上下文管理器和With语句精简代码
30 | 真的有必要写单元测试吗?
31 | pdb & cProfile:调试和性能分析的法宝
32 | 答疑(三):如何选择合适的异常处理方式?
量化交易实战篇 (8讲)
33 | 带你初探量化世界
免费
34 | RESTful & Socket: 搭建交易执行层核心
35 | RESTful & Socket: 行情数据对接和抓取
36 | Pandas & Numpy: 策略与回测系统
免费
37 | Kafka & ZMQ:自动化交易流水线
38 | MySQL:日志和数据存储系统
39 | Django:搭建监控平台
40 | 总结:Python中的数据结构与算法全景
技术见闻与分享 (4讲)
41 | 硅谷一线互联网公司的工作体验
42 | 细数技术研发的注意事项
加餐 | 带你上手SWIG:一份清晰好用的SWIG编程实践指南
43 | Q&A:聊一聊职业发展和选择
结束语 (1讲)
结束语 | 技术之外的几点成长建议
Python核心技术与实战
登录|注册

06 | Python “黑箱”:输入与输出

景霄 2019-05-22
你好,我是景霄。
世纪之交的论坛上曾有一句流行语:在互联网上,没人知道你是一条狗。互联网刚刚兴起时,一根网线链接到你家,信息通过这条高速线缆直达你的屏幕,你通过键盘飞速回应朋友的消息,信息再次通过网线飞入错综复杂的虚拟世界,再进入朋友家。抽象来看,一台台的电脑就是一个个黑箱,黑箱有了输入和输出,就拥有了图灵机运作的必要条件。
Python 程序也是一个黑箱:通过输入流将数据送达,通过输出流将处理后的数据送出,可能 Python 解释器后面藏了一个人,还是一个史莱哲林?No one cares。
好了废话不多说,今天我们就由浅及深讲讲 Python 的输入和输出。

输入输出基础

最简单直接的输入来自键盘操作,比如下面这个例子。
name = input('your name:')
gender = input('you are a boy?(y/n)')
###### 输入 ######
your name:Jack
you are a boy?
welcome_str = 'Welcome to the matrix {prefix} {name}.'
welcome_dic = {
'prefix': 'Mr.' if gender == 'y' else 'Mrs',
'name': name
}
print('authorizing...')
print(welcome_str.format(**welcome_dic))
########## 输出 ##########
authorizing...
Welcome to the matrix Mr. Jack.
input() 函数暂停程序运行,同时等待键盘输入;直到回车被按下,函数的参数即为提示语,输入的类型永远是字符串型(str)。注意,初学者在这里很容易犯错,下面的例子我会讲到。print() 函数则接受字符串、数字、字典、列表甚至一些自定义类的输出。
我们再来看下面这个例子。
a = input()
1
b = input()
2
print('a + b = {}'.format(a + b))
########## 输出 ##############
a + b = 12
print('type of a is {}, type of b is {}'.format(type(a), type(b)))
########## 输出 ##############
type of a is <class 'str'>, type of b is <class 'str'>
print('a + b = {}'.format(int(a) + int(b)))
########## 输出 ##############
a + b = 3
这里注意,把 str 强制转换为 int 请用 int(),转为浮点数请用 float()。而在生产环境中使用强制转换时,请记得加上 try except(即错误和异常处理,专栏后面文章会讲到)。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Python核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(105)

  • Jingxiao 置顶
    思考题第二题:(省略了一些异常处理,后面会讲到)
    server.py
    # 我们假设 server 电脑上的所有的文件都在 BASR_DIR 中,为了简化不考虑文件夹结构,网盘的路径在 NET_DIR

    import os
    from shutil import copyfile
    import time

    BASE_DIR = 'server/'
    NET_DIR = 'net/'

    def main():
        filenames = os.listdir(BASE_DIR)
        for i, filename in enumerate(filenames):
            print('copying {} into net drive... {}/{}'.format(filename, i + 1, len(filenames)))
            copyfile(BASE_DIR + filename, NET_DIR + filename)
            print('copied {} into net drive, waiting client complete... {}/{}'.format(filename, i + 1, len(filenames)))

            while os.path.exists(NET_DIR + filename):
                time.sleep(3)

        print('transferred {} into client. {}/{}'.format(filename, i + 1, len(filenames)))

    if __name__ == "__main__":
    main()

    ++++++++++++++++++++++
    client.py
    # 我们假设 client 电脑上要输出的文件夹在 BASR_DIR ,网盘的路径在 NET_DIR

    import os
    from shutil import copyfile
    import time

    BASE_DIR = 'client/'
    NET_DIR = 'net/'

    def main():
        while True:
            filenames = os.listdir(NET_DIR)
            for filename in filenames:
                print('downloading {} into local disk...'.format(filename))
                copyfile(NET_DIR + filename, BASE_DIR + filename)
                os.remove(NET_DIR + filename) # 我们需要删除这个文件,网盘会提我们同步这个操作,从而 server 知晓已完成
                print('downloaded {} into local disk.'.format(filename))
            time.sleep(3)

    if __name__ == "__main__":
    main()
    2019-05-26
    3
    29
  • Jingxiao 置顶
    思考题第一题:

    import re

    CHUNK_SIZE = 100 # 这个数表示一次最多读取的字符长度

    # 这个函数每次会接收上一次得到的 last_word,然后和这次的 text 合并起来处理。
    # 合并后判断最后一个词有没有可能连续,并分离出来,然后返回。
    # 这里的代码没有 if 语句,但是仍然是正确的,可以想一想为什么。
    def parse_to_word_list(text, last_word, word_list):
        text = re.sub(r'[^\w ]', ' ', last_word + text)
        text = text.lower()
        cur_word_list = text.split(' ')
        cur_word_list, last_word = cur_word_list[:-1], cur_word_list[-1]
        word_list += filter(None, cur_word_list)
        return last_word

    def solve():
        with open('in.txt', 'r') as fin:
            word_list, last_word = [], ''
            while True:
                text = fin.read(CHUNK_SIZE)
                if not text:
                    break # 读取完毕,中断循环
                last_word = parse_to_word_list(text, last_word, word_list)

            word_cnt = {}
            for word in word_list:
                if word not in word_cnt:
                    word_cnt[word] = 0
                word_cnt[word] += 1

            sorted_word_cnt = sorted(word_cnt.items(), key=lambda kv: kv[1], reverse=True)
            return sorted_word_cnt

    print(solve())
    2019-05-26
    8
    27
  • 不瘦到140不改名
    from collections import defaultdict
    import re

    f = open("ini.txt", mode="r", encoding="utf-8")
    d = defaultdict(int)

    for line in f:
        for word in filter(lambda x: x, re.split(r"\s", line)):
            d[word] += 1


    print(d)

    作者回复: 👍

    2019-05-22
    5
    29
  • 逆光飞翔
    老师,为什么filter(none,list)可以过滤空值,不是保留空值嘛

    作者回复: filter(None, Iterable) 是一种容易出错的用法,这里不止过滤空字符串,还能过滤 0,None,空列表等值。这里的 None,严格意义上等于 lambda x: x, 是一个 callable。

    2019-05-22
    2
    16
  • Geek_59f23e
    第一题:
    1、使用defaultdict初始化计数器更方便更快,不用再多做一步in判断,parse函数只需返回filter对象。

    2、读取大文件时使用for循环遍历迭代器,不占用内存空间,生成一行处理一行,就此例来说每一行行尾都是\n没有跨行单词,故此方法不用考虑边界问题,因文件中有多行\n,读取时做一步判断跳过避免再调用parse函数。

    word_cnt = defaultdict(lambda: 0)

    with open('in_big.txt', 'r') as fin:
        for line in fin:
            if line != '\n':
                for word in parse(line):
                    word_cnt[word] += 1

    第二题:
    说说思路,具体应该需要搭建web实现吧。

    1、server设置上传目录存放20个5G文件,开启while True进程检测网盘有无数据,数据为空时POST目录中5G文件,上传完毕后本地删除或者将其移出上传目录,直到上传目录为空时结束程序。

    2、client开启while True进程检测网盘有无数据,数据不为空时GET下载5G文件,下载完成后DELETE请求删除网盘数据。
    2019-05-22
    7
  • lmingzhi
    # 第一题, 修改parse函数,使其可以更新word_cnt
    import re
    def parse(text, word_cnt):
        # 转为小写
        text = text.lower()
        # 生成所有单词的列表
        word_list = re.findall(r'\w+', text)
        # 更新单词和词频的字典
        for word in word_list:
            word_cnt[word] = word_cnt.get(word,0) + 1
        return word_cnt

    # 初始化字典
    word_cnt = dict()
    with open('in.txt', 'r') as fin:
        for text in fin.readlines():
            word_cnt = parse(text, word_cnt)
            print(len(word_cnt))

    # 按照词频排序
    sorted_word_cnt = sorted(word_cnt.items(), key=lambda kv: kv[1], reverse=True)

    # 导出
    with open('out.txt', 'w') as fout:
        for word, freq in word_and_freq:
            fout.write('{} {}\n'.format(word, freq))

    作者回复: 👍

    2019-05-22
    7
  • Python高效编程
    第一问:
    with open("in.txt", "rt") as f:
        for line in f:
            Counter.update(line)

    作者回复: 想到 Counter 很棒,但是这样注意这样不行哦,Counter 初始化输入 str 会把 str 视作一个容器,最后 Counter 里存的全是单个字符和它的次数,而不是单词。

    2019-05-22
    5
  • 許敲敲
    这门课太值了 哈哈哈 我以前学到的真的toy python

    作者回复: 谢谢,加油!

    2019-05-22
    4
  • code2
    看到一片短文,摘录如下:
    数据科学家是“比软件工程师更擅长统计学,比统计学家更擅长软件工程的人”。许多数据科学家都具有统计学背景,但是在软件工程方面的经验甚少。我是一名资深数据科学家,在Stackoverflow的python编程方面排名前1%,并与许多(初级)数据科学家共事。以下是我经常看到的10大常见错误,本文将为你相关解决方案:

    删去前九个只余一个:

    使用jupyter notebook

    2019-05-23
    3
  • ........
    from collections import defaultdict
    import re

    d = defaultdict(int)

    with open('in.txt', 'r') as fin:
        text = fin.readline()
        while text:
            text = re.sub(r'[^\w ]', '', text)
            text = text.lower()
            word_list = text.split(' ')
        
            word_list = filter(None, word_list)
            for word in word_list:
                d[word] += 1
            text = fin.readline()
        
        # 按照词频排序
        sorted_word_cnt = sorted(d.items(), key=lambda kv: kv[1], reverse=True)
        



    2019-05-23
    3
  • 宝仔
    word_cnt = dict()!老师你之前不是说过:word_cnt = {}这样初始化字典不是效率更高吗?为什么你代码里用了函数初始化字典
    2019-05-23
    3
  • Lone
    第一题打卡
    import re

    def parse(text, word_cnt):
        text = text.lower()
        # print("--------------------{}".format(text))
        word_list = re.findall(r"\w+", text)
        # print(word_list)
        for word in word_list:
            word_cnt[word] = word_cnt.get(word, 0) + 1

        return word_cnt

    word_cnt = dict()

    # 读取文件
    with open("./in.txt", "r") as fin:
        for line in fin:
            word_cnt = parse(line, word_cnt)

    # print(word_cnt)

    word_and_freq = sorted(word_cnt.items(), key=lambda kv: kv[1], reverse=True)

    # print(word_and_freq)
    with open("./out.txt", "w") as fout:
        for word, freq in word_and_freq:
            fout.write("{} {}\n".format(word, freq))
    2019-05-22
    3
  • 人间乐园
    第一道,for.line in fin读取单行,使用result = yied line进行双向传递,直接把line给计数器,先判断line结尾处,如果是单词或者半个单词,则返回result给生成器,拼接到下一个line前,如果是None则不拼接,继续生成这个line。

    作者回复: 很棒的思路,但是注意如果原始文件只有一行呢?你想说的是读取一定长度的字符串吧

    2019-05-22
    3
  • Tango
    第七天打卡。

    作者回复: 👍

    2019-05-22
    3
  • 王豪
    老师,这样统计词频效率应该会高一些吧
    word_cnt={}
    for word in word_list:
        word_cnt[word] = word_cnt.get(word, 0) + 1
    2019-07-23
    2
  • 种种
    不管最后一个单词断不断都可以放到下次一起,总不会错。整个单词,放到下次没毛病,中断的单词放到下次,理应如此。
    2019-06-28
    2
  • -Deeplikesea-
    老师,我还没有看到github的代码呢?想学习一下您怎么写的。
    2019-06-17
    2
  • zxq
    老师,想请问一下python关于线程管理机制,举个例子来说:我有两个程序read.py和write.py,一个是负责读取info.txt内容,而另一个是将数据写入这个txt。由于我不知道两个python程序会不会同时被调用,假设调用write.py写入数据时,尚未释放txt的端口,这时候read.py被调用来读取数据,这时候就有冲突了。python如何处理这样的机制呢?如何优化这两个py文件,可不可以通过调用端口占用状态来解决呢?
    2019-05-22
    1
    2
  • vivien_zh
    努力跟上老师的进度。

    作者回复: 多实践,多编码,多思考,一定没问题的

    2019-05-22
    2
  • 孙有能希
    re.sub(r'[^\w ]', ' ', text) 是怎么替换掉标点符号和换行的?查了半天也没理解。
    2019-09-02
    2
    1
收起评论
99+
返回
顶部