比pip快100倍的Python包安装工具

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 简介 uv是一款开源的Python包安装工具,GitHub star高达56k,以性能极快著称,具有以下特性(官方英文原文): 🚀 A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more. ⚡️ 10-100x faster than pip. 🗂️ Provides comprehensive project management, with a universal lockfile. ❇️ Runs scripts, with support for inline dependency metadata. 🐍 Installs and manages Python versions. 🛠️ Runs and installs tools published as Python packages. 🔩 Includes a pip-compatible interface for a performance boost with a familiar CLI. 🏢 Supports Cargo-style workspaces for scalable projects. 💾 Disk-space efficient, with a global cache for dependency deduplication. ⏬ Installable without Rust or Python via curl or pip. 🖥️ Supports macOS, Linux, and Windows. 在Python MCP SDK的介绍中,也出现了We recommend using uv to manage your Python projects的字样,说明uv已经是一款实用性极强的工具。 ...

官网学习之控制流

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 if if语句是最常见的控制流: >>> x = int(input("Please enter an integer: ")) Please enter an integer: 42 >>> if x < 0: ... x = 0 ... print('Negative changed to zero') ... elif x == 0: ... print('Zero') ... elif x == 1: ... print('Single') ... else: ... print('More') ... More for for语句用来遍历: ## Create a sample collection users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'} ## Strategy: Iterate over a copy for user, status in users.copy().items(): if status == 'inactive': del users[user] ## Strategy: Create a new collection active_users = {} for user, status in users.items(): if status == 'active': active_users[user] = status range range函数生成数字序列: ...

跟着官网学习Python系列

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 开篇 个人而言,Python是写起来最顺手、看起来最喜欢的编程语言,也是实际工作中使用最多的编程语言。从Python入门,到完全使用Java,再回归Python,编程语言本质上是工具,与Excel、XMind无异。对于测试开发来说,要学习的东西很多,Python是可以作为基础技术深入学习的。第1次通过菜鸟教程学习Python,第2次阅读《流畅的Python》学习Python,第3次跟着官网学习Python。该系列文章参考的是Python3.13版本官方教程,期望学习者具有一定编程基础。 Python解释器 终端使用uv安装Python3.13: uv python install 3.13 查看安装位置: which python3.13 进入Python解释器: $ python3.13 Python 3.13 (default, April 4 2023, 09:25:04) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> 计算器 平时我们基本不会这样来写Python,但是可以当做计算器来用: >>> 2 + 2 4 >>> 50 - 5*6 20 >>> (50 - 5*6) / 4 5.0 >>> 8 / 5 # division always returns a floating-point number 1.6 >>> 17 / 3 # classic division returns a float 5.666666666666667 >>> >>> 17 // 3 # floor division discards the fractional part 5 >>> 17 % 3 # the % operator returns the remainder of the division 2 >>> 5 * 3 + 2 # floored quotient * divisor + remainder 17 >>> 5 ** 2 # 5 squared 25 >>> 2 ** 7 # 2 to the power of 7 128 >>> width = 20 >>> height = 5 * 9 >>> width * height 900 >>> 4 * 3.75 - 1 14.0 >>> tax = 12.5 / 100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ # In interactive mode, the last printed expression is assigned to the variable _ 113.0625 >>> round(_, 2) 113.06 Python也很适合用来学习算法,比如最简单的冒泡排序: ...

Python并发编程从入门到进阶

本文是Python进阶系列专题的最后一篇文章了,学习一下Python并发编程。懂得并发编程,就算是真正进阶了。

Python协程知多少

从概念上来说,我们都知道多进程和多线程,而协程其实是在单线程中实现多并发。从句法上看,协程与生成器类似,都是定义体中包含yield关键字的函数。区别在于协程的yield通常出现在表达式的右边:datum = yield。这一下就让初学者瞬间觉得yield关键字不香了,本来以为yield就是简简单单的暂停执行顺手返回个值,结果还能放右边?

Python上下文管理器

with语句会设置一个临时的上下文,交给上下文管理器对象控制,并且负责清理上下文。

长篇大论Python生成器

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Python生成器是什么 一句话解释:包含了yield关键字的函数就是生成器,它的返回值是一个生成器对象。我简单画了个示意图: yield相当于return。 函数遇到yield就暂停,保存当前信息,返回yield的值。 在下次执行next()时,从当前位置继续执行。 比较有意思的事情是,曾经有人建议生成器函数不应该使用def,而应该发明一个新的关键字比如gen,但是Python之父Guido并没有同意这样做。 生成器函数的工作原理 先通过一个简单示例来说明生成器的行为: ## 定义一个生成器 >>> def gen_123(): ... yield 1 ... yield 2 ... yield 3 ... ## 生成器本身是个函数 >>> gen_123 <function gen_123 at 0x0000019F60710790> ## 返回值是生成器对象 >>> gen_123() <generator object gen_123 at 0x0000019F606AC040> ## 生成器也是迭代器 >>> for i in gen_123(): ... print(i) ... 1 2 3 ## 验证生成器也是迭代器,定义迭代器g >>> g = gen_123() ## 可以通过next()获取yield生成的下一个元素 >>> next(g) 1 >>> next(g) 2 >>> next(g) 3 >>> next(g) Traceback (most recent call last): File "<input>", line 1, in <module> StopIteration 生成器的原理就是: 生成器函数会创建一个生成器对象。 把生成器传给next()函数时,生成器函数会执行函数定义体中的下一个yield语句,返回产出的值,并在当前位置暂停。 函数的定义体返回时,外层的生成器对象会抛出StopIteration异常 yield关键字一般是和for循环搭配使用的,在for循环中会隐式调用next()函数。 ...

Python可迭代的对象与迭代器的对比

什么是迭代?迭代是指按需一次获取一个数据。是否可以迭代,可以通过是否可以使用for循环取值来进行简单的判断。更准确的判断是使用iter()函数,这是一个Python内置函数。

Python抽象基类的定义与使用

我们写Python基本不需要自己创建抽象基类,而是通过鸭子类型来解决大部分问题。《流畅的Python》作者使用了15年Python,但只在项目中创建过一个抽象基类。我们更多时候是创建现有抽象基类的子类,或者使用现有的抽象基类注册。本文的意义在于,了解抽象基类的定义与使用,可以帮助我们理解抽象基类是如何实现的,为我们以后学习后端语言(比如Java、Golang)打下基础。**毕竟抽象

Python中的接口协议和抽象基类

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Python接口与协议 Python语言是没有interface关键字的,这也是动态类型语言的特点之一。Python的接口指的是类实现或继承的公开属性,包括数据或方法。比如Sequence的正式接口如下图所示: 这些都叫做Python接口。事实上,Python每个类都有接口,除了抽象基类。 接口是正式的,它定义了类具有哪些属性,协议是非正式的接口,只由文档和约定定义。比如只要类实现了__getitem__方法,按照序列协议的约定,Python就会支持这个类完成访问元素、迭代和使用in运算符等一系列操作。 猴子补丁 我们可以通过猴子补丁来进一步认识,Python中协议的约定是怎么回事。猴子补丁是这样一种技术:在运行时修改类或模块,而不改动源码。还是以序列协议来举例,比如: >>> from random import shuffle >>> from frenchdeck import FrenchDeck >>> deck = FrenchDeck() >>> shuffle(deck) 假设运行报错了:TypeError: 'FrenchDeck' object does not support item assignment,因为FrenchDeck类只有__getitem__方法,只实现了不可变的序列协议。为了解决这个报错,需要通过__setitem__方法实现可变的序列协议。 代码如下: def set_card(deck, position, card): deck._cards[position] = card FrenchDeck.__setitem__ = set_card shuffle(deck) 这就是一段猴子补丁技术的实现代码,没有修改FrenchDeck类的源码,而是在运行时动态修改。 抽象基类 Python的抽象基类是指必须让继承它的子类去实现它所要求的方法的类。Python的collections.abc模块中就定义了很多抽象基类: 虽然我们在实际编程中并不会自己编写抽象基类(一般也不建议这样做,因为可能会导致意想不到的问题),但是了解抽象基类,可以帮助我们更好理解Python面向对象的继承等概念。 抛开枯燥的理论知识,我在书中找到了一处具有实践价值的片段: 「在一连串if/elif/elif中使用isinstance做检查,然后根据对象的类型执行不同的操作,通常是不好的做法;此时应该使用多态,即采用一定的方式定义类,让解释器把调用分派给正确的方法,而不使用if/elif/elif块硬编码分派逻辑。」 交流群和公司都有人问过我这个问题,写了太多的ifelse有没有更好的实现方式,我想这里已经给出了答案。 鸭子类型和白鹅类型 Python鸭子类型是指对象的类型无关紧要,只要实现了特定的协议即可。它的好处是避免过多的isinstance,如果遵守既定协议,能增加利用现有的标准库和第三方代码的可能性。示例: class Animal(object): def run(self): print("The animal is running...") class Dog(Animal): def run(self): print('The dog is running...') class Cat(Animal): def run(self): print('The cat is running...') def make_run(animal): animal.run() dog = Dog() cat = Cat() make_run(dog) make_run(cat) 对于 make_run() 函数来说,传入的参数并不一定需要是 Animal 类型的,只需要保证传入的对象有一个 run() 方法即可。 ...