多值匹配:
1 2 3 4 5
match x: case 1 | 2 | 3: print("small") case _: # fallback print("big")
条件匹配:
1 2 3
match x: case n if n > 10: print("big")
匹配元组(联想到了haskell中的模式匹配)
1 2 3 4 5 6 7
point = (1, 2) match point: case (0, 0): print("origin") case (x, y): print(x, y)
匹配dict:
1 2 3 4 5 6 7
task = {"type": "bug_fix", "scope": "large"} match task: case {"type": "bug_fix"}: print("fix bug") case {"type": "refactor", "scope": "large"}: print("big refactor")
匹配类:
1 2 3 4 5 6 7 8 9 10 11 12
from dataclasses import dataclass @dataclass class Task: type: str scope: str t = Task("bug_fix", "small") match t: case Task(type="bug_fix"): print("fix bug")
调用普通函数的时候,会一直等待其返回;但是有些函数在执行的时候,本身并不需要持续占用CPU (比如IO密集型的任务,网络读取、数据库读取、文件IO), 如果能够在它处理的时候,将CPU让出去,会提高整体的效率.这就是异步函数.
定义的时候,加上async关键字:
1 2 3 4 5 6 7 8
import asyncio async def foo(): print("hello") return 123 result = asyncio.run(foo()) print(result)
await函数表示:(在一个异步函数内暂停) 等待一个异步操作执行完毕。但是在这个期间,CPU可以让给别的事情.
1 2 3 4 5 6
import asyncio async def foo(): print("start") await asyncio.sleep(1) print("end")
await只能用在一个异步函数中;而asyncio.run()则是在最外层同步代码里启动事件循环并运行一个异步函数.
faq: 既然在一个async函数中,可以通过await调用另一个async函数,那么能不能直接写成普通的函数调用形式呢? 事实上,按照普通的方式“调用”异步函数只会返回一个协程对象;想要让它跑起来,还是要用await.
使用tomblib库.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
resolved_path = resolve_config_path(config_path) if not resolved_path.exists(): return AppConfig(config_path=resolved_path) # open (resolved_path: Path) with resolved_path.open("rb") as file: # load toml file, return dict object raw_config = tomllib.load(file) raw_agent = raw_config.get("agent", {}) if raw_agent is None: raw_agent = {} if not isinstance(raw_agent, dict): raise ValueError("'agent' must be a TOML table.") raw_rule = raw_config.get("rule", {}) if raw_rule is None: raw_rule = {} if not isinstance(raw_rule, dict): raise ValueError("'rule' must be a TOML table.") agent_config = AgentConfig( max_steps_per_turn=int(raw_agent.get("max_steps_per_turn", AgentConfig.max_steps_per_turn)), ... )
1 2
class A(B): ...
意为继承自B类,如果不加括号,直接定义class,默认继承自Object类.
可以继承自Enum,实现枚举类:
1 2 3
from enum import Enum class A(Enum): ...
有时候,如果只是想限制某个字段的value 类型,可以使用Literal
1 2 3 4 5 6 7 8
from typing import Literal def move(direction: Literal["left", "right"]): ... Color = Literal["red","green","blue"] class Flower: color: Colorl
Path 对象支持一系列方便的读写方法,例如read_text, read_bytes, write_text, write_bytes. 源码:
1 2 3 4 5 6 7 8 9
def read_text(self, encoding=None, errors=None, newline=None): """ Open the file in text mode, read it, and close the file. """ # Call io.text_encoding() here to ensure any warning is raised at an # appropriate stack level. encoding = io.text_encoding(encoding) with self.open(mode='r', encoding=encoding, errors=errors, newline=newline) as f: return f.read()
在一个目录下增加__init__.py意味着被当作package, 可以在其他地方import. 而且__init.py__中的代码在被import的时候,会自动执行.
还可以手动指定__all__变量,控制对外暴露的内容。例如:
1 2 3
a = 1 b = 2 __all__=["a"]
在其他地方导出的时候,只包含a变量.
可以使用rich库.
1 2
from rich import print print("[blue]Hello World! [/blue]")
1 2 3
from rich import print from rich.markdown import Markdown print(Markdown("### hello"))
1
from rich.console import Console
执行uv pip install -e .的时候,会在当前的虚拟环境中,安装当前项目注册的命令。这些命令通常在pyproject.toml中定义,如:
1 2 3 4
[project.scripts] ida-cli = "arida.cli:main" launch-ida = "arida.headless:main" idapython = "arida.idapython:main"
而-e代表“可编辑安装”,并不会拷贝所有代码,而是将其链接到当前的目录中.