Post

Python Note - 01

python中的match

多值匹配:

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")

异步函数,async和await关键字

调用普通函数的时候,会一直等待其返回;但是有些函数在执行的时候,本身并不需要持续占用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.

tomb解析

使用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)),
        ...
    )

python类继承、枚举、Literal

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

python Path

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()

python init.py

在一个目录下增加__init__.py意味着被当作package, 可以在其他地方import. 而且__init.py__中的代码在被import的时候,会自动执行.

还可以手动指定__all__变量,控制对外暴露的内容。例如:

1
2
3
a = 1
b = 2
__all__=["a"]

在其他地方导出的时候,只包含a变量.

markdown终端渲染/彩色渲染

可以使用rich库.

  • 彩色
    1
    2
    
    from rich import print
    print("[blue]Hello World! [/blue]")
    
  • markdown
    1
    2
    3
    
    from rich import print
    from rich.markdown import Markdown
    print(Markdown("### hello"))
    
  • console [TODO]
    1
    
    from rich.console import Console
    
This post is licensed under CC BY 4.0 by the author.