Python 执行系统命令 - subprocess 模块的使用

Python 可信手拈来写系统脚本,那么在 Python 中调用系统命令应该会比较便捷。所以本文来看看 Python 有几种方式调用系统命令,以及与回味一下其他几种脚本语言的类似操作。简单说来,Python 执行系统命令的方式有四种方式,即

  1. os.system(cmd) (建议用 subprocess 模块)
  2. os.popen(cmd) (Python 3 中还能用,但不推荐使用了)
  3. commands 模块(在 Python 3 中已移除了该模块,基本是不必去了解它)
  4. subprocess 模块(总是上面的矛头全指向它的,重点)

os.system(cmd)

启动一个子进程来执行系统命令,可以获得标准输入,不能获到命令输出, 但可以得到一个状态码 阅读全文 >>

Python 函数声明先后顺序的问题

在 Python 中如果把函数定义写在调用的下方可能会出错,例如下面的代码

foo()

def foo():
    print("hello")

执行时会报出错误

NameError: name 'foo' is not defined

这时候要把 foo() 调用代码放到该函数的声明后面

def foo():
    print("hello")

foo()

这样执行就一切正常了。这仿佛像是 C 语言中的函数调用需要提前声明一般,例如在 C 语言中要调用后头的定义的函数要写成 阅读全文 >>

AWS Python Lambda 使用 Layer

使用 Python 书写 AWS Lambda 的一个好处就是能够在控制台中直接编辑源代码,非常方便进行快速验证测试 AWS 环境相关的。这只限于使用 AWS 为 Python Lambda 运行时提供的默认组件(比如 boto3),尚若需要在自己的 Python Lambda 中使用其他的组件(如 redis), 就不得不把自己的代码及依赖打成一个 zip 包再部署,这时候就无法在控制台直接编辑代码了,也只能坠入本地修改代码,重新打包上传测试的循环当中。

欲了解 Python Lambda 中除了 boto3 外还能直接使用别的什么组件,可点击此链接 https://gist.github.com/gene1wood/4a052f39490fae00e0c3 查看当前。该 gist 也还提供了代码 code to run in Lambda 来获得所有依赖。试了下在 Python Lambda 中,用通常的

help('modules')    # 或
help('modules package')

竟然连大名鼎鼎的 boto3 都无法列出来。

回到正题来,如果既想用第三方的依赖,又想要在控制台中直接编辑代码进行测试,是否有他法呢?有,那就是 AWS 在 2018 年 11 月推出的 Lambda 层。见 AWS Lambda Now Supports Custom Runtimes and Enables Sharing Common Code Between Functions, 这里的层除了能用来提供 Python 依赖,还许自定义运行时,如 C++ 或 Rust 等写 Lambda 都不是梦。

AWS 的服务就像个大口袋,何时偷偷的加添了什么服务,或出了什么新的我,不时关注它的 What's New with AWS 必是个好习惯。 阅读全文 >>

开启 Python 组件 Boto3 在 IDE 中的智能提示

在用 Python 编写 AWS 服务时,要用到 Boto 3 组件,而像 boto3.client('s3') 获得的对象只能被 IDE 识别为一个 BaseClient, 具体包含什么操作方法是在运行时由参数 s3 指示的基于 JSON 文件所描述的。因此 IDE 对 s3 = boto3.client('s3')s3 对象无法提供有效的智能提示,每次用 Boto 3 时不得不打开 Boto 3 的在线 API 文档来对照。长此以往,总觉麻烦且效率低下,有种一直摸着石头过河的感觉。那么,是否有办法让 IDE 智能提示出各种 boto3.client('<service>') 的实际操作呢?网上找了找,确实有这个需求,解决办法有

  1. botostubs: 与 boto3 API 保持更新(每三天),并支持众多 IDE, 试过在 IntelliJ IDEA 和 Visual Studio Code 中可用
  2. pyboto3: 上次更新在两年前, https://github.com/wavycloud/pyboto3, 只在 Python 2.7 下测试过
  3. autoboto: 需有智能提示,但改变了应用 Boto 3 组件的方式,不建议使用

本文重点推荐 botostubs, 下面会叙说具体理由,在进入正是之前,不妨来回顾一下直接使用 Boto 3 时没有好的智能提示的问题 阅读全文 >>

Python 常用日期处理 -- calendar 与 dateutil 模块

本文紧承上一篇 Python 常用日期处理,因制于篇幅的大小需求才临时分立新篇,这里要简单提到 calendar 和 dateutil 模块的使用,其中 calendar 是 Python 内置的。相比于上一篇而言,此处主旨会更明确一些,只记录三个应用案例,分别是

  1. 用 dateutil 灵活的解析 datetime 字符串
  2. 给定起始日期后的连续日期
  3. 给定起始日期后连续的月末日期

dateutil 灵活的解析 datetime 字符串

使用 Python 内容的  date 或 datetime, 构造它们的实例时需要逐个的传入年月日或时分秒,或者要调用  fromisoformat() 方法解析严格的字符串表示格式。而 dateutil.parser 的 parse() 方法就显得特别的聪明和随意,它可以智能的解析更丰富的字符串表示方式。详细的支持格式请参考官方文档的 parse examples,恐怕官方文档也未列举完全,只要觉得合理的时间字符串就可以尝试去解析。下方是一些例子 阅读全文 >>

Python 常用日期处理 -- 内置模块 datetime

仅以此篇记录一下个人常用的 Python 处理日期的库与函数,主要涉及的类库有 Python 自带的 datetime, timecalendar,以及第三方的 dateutil。说到日期处理基本上要覆盖的概念有 date, time, datetime, timezone, calendar, 时间的比较与差值,解析与格式化显示等。

在 datetime 模块中类之间的继承关系如下:

object
├── date
│      └── datetime
├── time
├── timedelta
└── tzinfo
         └── timezone

我们着重体验一下前面粗体显示的 datetime, date, time, timedelta 对象, timezone 也不是不重要,有时候也可能只需要处理本地时间。 阅读全文 >>

Python 对象当函数使及动态添加方法

继续阅读 《Python Tricks: The Book》,书中说到 "Objects Can Behave Like Functions", 就是把对象当成函数来调用,在普通对象后加个括号就能调用相应的 __call__ 函数。下面是书中的例子

class Adder:
    def __init__(self, n):
        self.n = n

    def __call__(self, x):
        return self.n + x

然后是应用类 Adder 的代码

plus_3 = Adder(3)
plus_3(4)  # 普通对象 plus_3 当成函数来用

上面 plus_3 是一个普能的对象,并非一个函数,但如果把它当成函数来看待,那么 plus_3(4) 就会去寻找相应的 __call__ 函数。 阅读全文 >>

Python 函数参数的拆解

本文为阅读 《Python Tricks: The Book》一书的 3.5 Function Argument Unpacking 的笔记与扩充理解。函数参数拆解是定义可变参数(VarArgs) *args 和 **kwargs 的反向特性。

*args 和 **kwars 是函数可定义一个形参来接收传入的不定数量的实参。

而这里的函数参数拆解是形参定义多个,在调用时只传入一个集合类型对象(带上 * 或 ** 前缀),如 list, tuple, dict, 甚至是 generator, 然后函数能自动从集合对象中取得对应的值。

如果能理解下面赋值时的参数拆解和 Python 3.5 的新增 * ** 操作,那么于本文讲述的特性就好理解了。

唯一的不同时作为参数的集合传入函数时必须前面加上 * 或 **, 以此宣告该参数将被拆解,而非一个整体作为一个函数参数。加上 * 或 ** 与 Java 的 @SafeVarargs 有类似的功效,最接近的是 Scala 的 foo(Array[String]("d", "e") : _*) 写法。参见:Java 和 Scala 调用变参的方式 阅读全文 >>

Python 集合的遍历,推导及 filter/map/reduce 操作

借鉴于其他多数语言中集合的 map/reduce 操作,也想总结一下在 Python 中如何对集合进行 map/reduce。而不是对于 Python 集合只会用简单的 for ... in 遍历,处于之间的是 Python 的  Comprehension 操作,更倾向于译作推导; 在 Scala 中也有类似的  for-comprehension 语法。

因此本文将涉及到三个方面的知识,基本的集合遍历操作,集合的推导,与 filter/map/reduce 操作。我无法写出诸如 掌握 Python 集体看这一篇就够了 的文章,但基本由本篇出发能了解到 Python 集合的基本遍历,转换操作。其余如切片,和更多能作用于 Python 集合的函数未有提及, 请查阅相关文档。

集合的基本遍历操作

这一块主要是复习功课, 希望由此熟练掌握常用的集合遍历操作方式 阅读全文 >>

Python 多线程编程

这几天一直浸淫在对 Python 的学习当中,对于一个更习惯 Java 语言的人来说,在接接触 Python 各种概念时会不停的与 Java 进行碰撞。譬如这里要说到的线程,Python 能如何像 Java 一样创建并执行单个线程,以及是否也能使用线程池来进行多作务的执行呢?

整个读完了《THE Quick Python Book》一书也只字未提多线程,然而对于有长时间的 IO 等待的程序,对于当今普及的多核以及核内超线程的 CPU 来说,不使用多线程来并行或并发处理任务是万万不能的,否则效率的差别是数量级的。

基于与 Java 多线程编程进行的比较,主要着力于两个问题:1)创建并执行新的线程,2)线程池中执行任务

创建并执行新的线程

默认的,代码是在主线程中执行,主线程名称为 MainThread。如果要创建一个子线程并执行需要用到模块 threading。下面的是基本的代码 阅读全文 >>