一日一技:让你的正则表达式可读性提高一百倍
正则表达式这个东西,强大是强大,但写出来跟个表情符号一样。自己写的表达式,过一个月来看,自己都不记得是什么意思了。比如下面这个:1pattern = r"((?:\(\s*)?[A-Z]*H\d+[a-z]*(?:\s*\+\s*[A-Z]*H\d+[a-z]*)*(?:\s*[\):+])?)(.*?)(?=(?:\(\s*)?[A-Z]*H\d+[a-z]*(?:\s*\+\s*[A-Z]*H\d+[a-z]*)*(?:\s*[\):+])?(?![^\w\s])|$)"有没有什么办法提高正则表达式的可读性呢?我们知道,提高代码可读性的方法之一就是写注释,那么正则表达式能不能写注释呢?例如对于下面这个句子:1msg = '我叫青南,我的密码是:123kingname456,请注意保密。'我要提取其中的..
更多一日一技:如何让自己的工具函数在Python全局可用?
我们在开发Python项目的时候,经常会写一些工具函数。为了在项目里面多个.py文件中使用这个工具函数,就不得不在多个地方都导入它,非常麻烦。例如下面这个例子:在A.py和C.py文件都要使用clean_msg这个工具函数,那么他们就都要从util.py中导入clean_msg。这似乎理所当然。但今天我在看icecream/builtins.py源代码的时候,突然发现了一个高级用法,可以让我们使用工具函数的时候,就像使用Python的print函数一样,不用导入,而是直接使用。我们先来看看效果:大家注意A.py和C.py,我并没有导入clean_msg而是直接使用了这个函数。并且运行完全正常。关键原理就在入口文件main.py,被我框住的3行:1234import builtinsfrom util im..
更多一日一技:Any与TypeVar,让IDE的自动补全更好用
相信有很多同学在写Python的时候,会使用类型标注来提高代码的可读性,同时还能帮助IDE实现自动补全。假设我们现在获得了一个对象,这个对象可能是列表也可能是生成器,我写一个函数,获取它的第一个元素。代码很简单:123456789101112131415161718192021222324252627282930313233from typing import Iteratorfrom contextlib import suppressclass People: def __init__(self, name): self.name = name def eat(self): print(f'{self.name}正在吃饭') def walk(self):..
更多一日一技:如何从大量商品数据里面找到降价商品?
相信很多做爬虫的同学都会爬电商网站,每天爬一次,然后监控商品是否降价。如果你只监控一个商品,那么是否降价这非常容易判断,但如果你要找到这个网站里面所有降价的商品,那就非常麻烦了。如下图所示,是美国电商沃尔玛的全站商品数据:每个商品每天都会爬一次,一共有61w+条数据。里面有N个商品降价了,现在需要把这些降价的商品找出来。商品有十几万个,如果你分别找到每个商品的ID,然后用ID再找到这个商品每一天的数据,最后看它是否降价,这个工作量非常大,速度也会非常慢。Pandas内部使用了SIMB技术来对并行计算进行优化,我们需要尽量在不使用for循环的情况下,完成这个任务。为了简单起见,我们假设降价就是指今天比昨天的价格低,不考虑先涨价再降价的情况。要解决这个问题,我们需要使用DataFrame的pct_change..
更多一日一技:用Python做游戏有多简单
我520的公众号图片发了以后,有很多同学问我这个游戏是怎么做的,难不难。我就用两篇文章来介绍一下,如果使用Python做游戏。这个游戏是使用PyGame做的,贴图素材是从itch.io找的。我之前也没有用过PyGame,这次属于是现学现用,参考的教程是PyGame: A Primer on Game Programming in Python。用PyGame做游戏非常简单,我们今天第一篇文章,让大家实现一个可以在地图上移动的小猪。基本框架首先,无论你是做什么游戏,别管三七二十一,先把下面这段代码复制粘贴到你的编辑器里面。所有游戏都需要这几行代码:123456789101112131415import pygamedef main(): pygame.init() pygame.display...
更多轻量级任务队列RQ的简单使用
RQ (Redis Queue)是一个轻量级的Python任务队列,这里记录一下它的简单使用。首先安装RQ(这里使用的Python版本是3.8.0)pip install rq==1.10.1随后创建如下的文件.├── __init__.py├── jobs.py└── run.py其中__init__.py中通过连接redis-server创建了两个queue:default和queue_1123456from redis import Redisfrom rq import Queueredis_conn = Redis('127.0.0.1', db=0)rq_default_queue = Queue('default', connection=redis_conn)rq_queue_1 = Qu..
更多一日一技:如何批量给PDF添加水印?
我们有时候需要把一些机密文件发给多个客户,为了避免客户泄露文件,会在机密文件中添加水印。每个客户收到的文件内容相同,但是水印都不相同。这样一来,如果资料泄露了,通过水印就知道是从谁手上泄露的。今天,一个做市场的朋友找我咨询一个加水印的问题,如下图所示:他有一个Excel文件,文件里面有10000个经销商的名字,他要把价目表PDF发给这些经销商,每个经销商收到的PDF文件上面的水印都是这个经销商自己的名字。这个需求手动操作肯定要累死人。但是如果用Python来做,就非常简单。代码不超过30行。准备环境要完成这个需求,需要安装两个模块,分别叫做reportlab和pikepdf。使用Pip安装就可以了:1python3 -m pip install reportlab pikepdf然后,需要找到一个.ttf..
更多使用Celery实现Python分布式任务处理
Celery是一个任务队列,它可以实现跨进程和机器的分布式任务处理。任务队列的输入端会输入各种任务(task),这些任务会在输出端由worker进行处理,这些任务会由客户端通过发送消息的方式交给broker,随后broker把任务分发给worker。安装组件本文使用到的组件版本组件版本Python2.7.16Celery4.4.7Redis6.2.4redis-py3.2.1首先我们需要安装celery和Redis的依赖包pip install celery==4.4.7pip install redis==3.2.1Celery支持多种类型的broker,在这里我们主要使用Redis作为Celery的broker,关于Redis的安装和使用可以参考我之前的文章Redis failover。构建应用我们首..
更多Python图表库Matplotlib 组成部分介绍
图表有很多个组成部分,例如标题、x/y轴名称、大刻度小刻度、线条、数据点、注释说明等等。我们来看官方给的图,图中标出了各个部分的英文名称Matplotlib提供了很多api,开发者可根据需求定制图表的样式。前面我们设置了标题和x/y轴的名称,本文介绍更多设置其他部分的方法。绘图先绘制一个事例图。然后以此为基础进行定制。123456789101112131415161718def demo2(): x_list = [] y_list = [] for i in range(0, 365): x_list.append(i) y_list.append(math.sin(i * 0.1)) ax = plt.gca() ax.set_title('r..
更多开始使用 Beancount
使用 Beancount 记账已经有将近两个月了,简单写一写我都做了什么。 注:本文只是一个流水账,并不是一个 Beancount 使用教程,如果想详细了解 Beancount 的话,可以参考下面提到的那些文章。 一些背景 Beancount 是什么 如上文所说,Beancount 是一个记账工具,更准确些来讲,是一个复式记账工具。但直到我写这篇文章的时候才发现官方将其定义为“一种复式记账计算机语言”。 简单来讲,它可以让你以纯文本方式记账,并通过一种类 SQL 的语言来对交易进行查询。记账文件还可以配合 Git 进行版本控制。 此外,Beancount 官方提供了一个名叫 fava 的图形化管理工具,它基于 Web,能够提供比原生页面更加丰富的内容,一般记账所需要的信息一目了然。想体验的同学可以在..
更多