• 神奇的弱引用

    背景 开始讨论弱引用( weakref )之前,我们先来看看什么是弱引用?它到底有什么作用? 假设我们有一个多线程程序,并发处理应用数据: 1 2 3 4 # 占用大量资源,创建销毁成本很高 class Data: def __init__(self, key): pass 应用数据 Data 由一个 key 唯一标识,同一个数据可能被多个线程同时访问。由于 Data 需要占用很多系统资源,创建和消费的成本很高。我们希望 Data 在程序中只维护一个副本,就算被多个线程同时访问,也不想重复创建。 为此,我们尝试设计一个缓存中间件 Cacher : 1 2 3 4 5 6 7 8 9 10 11 12 13 import threading # 数据缓存 class Cacher: def __init__(self): self.pool = {} self.lock = threading.Lock() def get(self, key): with self.lock: data = self.pool.get(key) if data: return data self.
    阅读全文
  • deque 对象,快如闪电的双端队列

    我们已经学习了 list 对象的内部结构,知道它底层是用动态数组实现的。在 list 头部进行插入或删除,都要挪动其后的所有数据,性能非常差!因此,我们不能将 list 对象作为队列使用。 好在 Python 标准库提供了另一种对象—— deque ,很好地补全了 list 的短板。deque 是一种类似 list 的线性表,但它在两端插入删除数据的时间复杂度都是 $O(1)$ ,因而可以作为队列来使用。 1 2 3 4 5 6 7 8 9 10 from collections imoprt deque # 创建一个deque对象作为队列 q = deque() # 数据入队:将其插到末尾 q.append(data) # 数据出队:从头部弹出 data = q.popleft() 您可能会问了,deque 到底跟 list 有何不同?为何两端都能同时支持 $O(1)$ 的插入删除呢? 内部结构 这其中的秘密还得到源码中寻找。Python标准库位于源码中的 Lib 目录,collections 模块源码位于 Lib/collections 目录,模块入口文件为 Lib/collections/__init__.py 。打开 __init__.py 可以看到这段代码( 29~34 行): 1 2 3 4 5 6 try: from _collections import deque except ImportError: pass else: _collections_abc.
    阅读全文
  • tabulate

    用过 MySQL 的童鞋一定对那个非常好看的字符表格印象深刻吧!

    Python 中,使用 tabulate 库,可轻松实现一模一样的字符表格。

    快速上手

    废话不多说,先来看看效果:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
        >>> from tabulate import tabulate
    
        >>> table_header = ['Name', 'Chinese', 'Math', 'English']
        >>> table_data = [
        ...     ('Tom', '90', '80', '85'),
        ...     ('Jim', '70', '90', '80'),
        ...     ('Lucy', '90', '70', '90'),
        ... ]
    
        >>> print(tabulate(table_data, headers=table_header, tablefmt='grid'))
        +--------+-----------+--------+-----------+
        | Name   |   Chinese |   Math |   English |
        +========+===========+========+===========+
        | Tom    |        90 |     80 |        85 |
        +--------+-----------+--------+-----------+
        | Jim    |        70 |     90 |        80 |
        +--------+-----------+--------+-----------+
        | Lucy   |        90 |     70 |        90 |
        +--------+-----------+--------+-----------+
    
    阅读全文
  • 一文说清文本编码那些事

    一直以来,编码问题像幽灵一般,不少开发人员都受过它的困扰。

    试想你请求一个数据,却得到一堆乱码,丈二和尚摸不着头脑。有同事质疑你的数据是乱码,虽然你很确定传了 UTF-8 ,却也无法自证清白,更别说帮同事 debug 了。

    有时,靠着百度和一手瞎调的手艺,乱码也能解决。尽管如此,还是很羡慕那些骨灰级程序员。为什么他们每次都能犀利地指出问题,并快速修复呢?原因在于,他们早就把编码问题背后的各种来龙去脉搞清楚了。

    本文从 ASCII 码说起,带你扒一扒编码背后那些事。相信搞清编码的原理后,你将不再畏惧任何编码问题。

    阅读全文
  • 用 Python 读写 Excel 表格

    Python 可以读写 Excel 表格吗?

    当然可以。 Python 下有很多类库可以做到, openpyxl 就是其中的佼佼者。

    openpyxl 的设计非常漂亮 ,你一定会喜欢它!不信请往下看:

    工作簿

    开始 openpyxl 前,无需提前建好工作簿( Workbook )。 只需导入 Workbook 类,便可在内存中创建新工作簿并开始操作:

    1
    2
    
    >>> from openpyxl import Workbook
    >>> wb = Workbook()
    
    阅读全文
  • 用 Python 生成 HTML 表格

    邮件报表 之类的开发任务中,需要生成 HTML 表格。

    使用 Python 生成 HTML 表格基本没啥难度, for 循环遍历一遍数据并输出标签即可。 如果需要实现合并单元格,或者按需调整表格样式,就比较麻烦了。

    这时,可以试试本文的主角 —— html-table 包,借助它可生成各种样式的 HTML 表格。 接下来,以一个简单的例子演示 html-table 的常用用法:

    表格效果图

    阅读全文
  • 更优雅地造测试数据

    开发系统时,经常需要一些伪数据用于测试。

    举个例子,设计一个学生管理系统,测试注册功能,总需要一些用户信息吧。我猜大部分人都会填:用户 aaaa ,密码 1111 ,手机号码 1111 ……感觉略无追求~

    那么有没有办法造一个看上是真的数据呢?自己造很累,有没有不需要大脑的方法的?

    还真有,这就是本文要介绍的一个Python模块——Faker

    阅读全文
  • 使用GDB调试Python程序

    最近用在开发一个 agent 程序,需要支持 LinuxFreeBSDWindows 等操作系统。 复杂的机器环境,导致一系列诡异问题,尽管代码发布前在不少测试机上验证过。

    Python 程序吐 coredump 文件怎么办? 很多人会想到用 gdb 加载 coredump 文件,然后查看 信号堆栈 信息,据此分析原因。 堆栈信息在调试中非常有用,可别忘了,待调试的是 Python 代码,而 gdb 提供的是 C 堆栈信息! 难道要撸 Python 源码,然后分析各种核心数据结构吗? 有什么方式可以查看到 Python 堆栈信息吗?

    还遇到过另一个问题,一个 Python 进程突然间陷入死循环,所有其他线程都调度不到。 遇到这种情况,首先可能需要知道死循环到底在干什么。 如何获悉呢?可能用 strace 跟一下系统调用可以看出一点端倪。 但是一个堆栈信息更为具体更有说服力,就算是只有 C 堆栈信息有时也是足以说明问题的。

    gdb 就可以解决以上难题(其实远不止),接下来,我们一起看看具体要怎么操作吧~

    阅读全文