doc: 阅读python文档

This commit is contained in:
asahi
2025-08-18 02:34:42 +08:00
parent 0e2445ccbf
commit e2fe983467

View File

@@ -94,6 +94,15 @@
- [packages](#packages) - [packages](#packages)
- [import \* from package](#import--from-package) - [import \* from package](#import--from-package)
- [包内部相互引用](#包内部相互引用) - [包内部相互引用](#包内部相互引用)
- [class](#class)
- [python scope and namespaces](#python-scope-and-namespaces)
- [namespace](#namespace)
- [lifetime](#lifetime)
- [LGEB](#lgeb)
- [scope](#scope)
- [global](#global)
- [nonlocal](#nonlocal)
- [global namespace](#global-namespace)
# Python # Python
@@ -1055,6 +1064,8 @@ except* OSError as e:
except* SystemError as e: except* SystemError as e:
print("There were SystemErrors") print("There were SystemErrors")
``` ```
当使用`except*`语法时,即使指定了`except* OSError as e``e`的类型仍然是`ExceptionGroup`而不是`OSError`因为try中抛出的`ConditionGroup`中可能含有多个`OSError`类型的异常,故而,实际的`OSError`异常对象需要通过`e.exceptions`来进行访问。
### enriching exceptions with notes ### enriching exceptions with notes
当创建异常时,可以通过`add_note(note)`方法来为异常补充信息标准的traceback会按照其被添加的顺序渲染所有的note信息note信息在异常信息之后 当创建异常时,可以通过`add_note(note)`方法来为异常补充信息标准的traceback会按照其被添加的顺序渲染所有的note信息note信息在异常信息之后
```py ```py
@@ -1570,4 +1581,113 @@ from .. import formats # 访问../formats
from ..filters import equalizer # 访问../filters中的equalizer from ..filters import equalizer # 访问../filters中的equalizer
``` ```
## class
python在对对象进行传递时只支持引用传递传递指向对象的指针而不支持类似c++的值传递对象拷贝。故而在python中如果对方法的入参对象进行了修改那么该修改对调用方可见。
### python scope and namespaces
#### namespace
namespace代表name到object的映射。
常见的namespace有
- 包含built-in names的namespacebuilt-in names包含类似`abs`之类的built-in函数以及built-in exception names等
- 包含module global names的module namespace
- 在函数调用时包含`local names`的local namespace
从某种意义上说对象中的attributes也构成了一个namespace。
对于`module.name`的访问,其实际也是针对`module object`中`attribute`的访问module中的global name和module attribute都是位于同一namespace中。
`attribute`分为`read-only`和`writable`的。对于`writable`的attribute可以对其进行赋值示例如下
```py
modname.the_answer = 42
```
同样的,`writable`的attribute也可以通过`del`来进行删除删除后该attribute将会从对象中被移除
```py
del modname.the_answer
```
##### lifetime
在不同时机创建的namespace拥有不同的生命周期
- `built-in namespace`: 在python interpreter启动时被创建并且该namespace永远不会被删除
- `module namespace`: 当module的定义被读入时会创建module namespace并且module namespace会持续到interpreter退出时
- 对于被interpreter执行的top-level statements通过交互式输入或从script中读取其被视作`__main__`module的一部分其拥有属于自己的namespace
- `local namespace of function`:在函数被调用时创建,在函数执行完成/抛出未处理异常时namespace被删除对于递归调用每次调用都拥有其自己的namespace
##### LGEB
在python中LEGB规则决定了命名空间搜索的顺序
- `local`: 定义在函数/类内部
- `enclosed`:定义在闭包函数内
- `global`:定义在全局/最上层
- `built-in`python中内置的保留名称
<img src="https://picx.zhimg.com/v2-9e322a731ae838a75dd2de84dae659e7_1440w.jpg" data-size="small" data-rawwidth="300" data-rawheight="260" data-original-token="v2-00f7cd30194a00ffd46c4fd5612b82c2" class="content_image" width="300">
##### scope
scope代表python程序中的一个文本范围在该范围内可以对某个namespace中的name进行直接访问而无需前缀`x.y.`之类的限定名。
在程序执行的某个时间点都会存在3/4个nested scopes可以直接访问
- 最内层的scope包含local names最先查找
- scope of enclosing function查找时会从nearest neclosing scope开始包含`non-local and non-global names`
- `next-to-last scope`包含global names
- 最外层scope最后查找包含built-in names
##### global
如果使用`global var_name`的方式来声明变量那么针对该变量的引用和复制都会直接指向global namespace中的变量。
##### nonlocal
如果想要在local namespace中访问enclosing namespace中的name可以通过`nonlocal var_name`形式来声明变量,示例如下:
```py
def main():
s = "fuck"
def s_change(p):
nonlocal s
s=p
s_change("shit")
print(s)
```
如果没有通过`nonlocal`进行声明那么对于s的赋值将会看作是`在innermost scope中创建了一个同名变量并进行赋值`,外部的变量值并不会改变。
通常来说在函数定义内scope为innermost scope而在函数外则是global namespace`类定义会新开一个namespace`。
##### global namespace
对于module中定义的function其global namespace即是module namespace无论函数在哪里被调用。
在python中如果没有使用`global`或`nonlocal`那么变量是只读的对name的赋值永远会在innermost scope中。`del`语句则是从local scope对应的namespace中移除变量的绑定。
> 当在innermost scope中如果只对外层变量进行读操作那么无需使用`global`或是`nonlocal`;但是,如果想要修改外层变量,则需要使用`global`或者`nonlocal`,否则外层变量是只读的。
```py
def scope_test():
def do_local():
spam = "local spam"
def do_nonlocal():
nonlocal spam
spam = "nonlocal spam"
def do_global():
global spam
spam = "global spam"
spam = "test spam"
do_local()
print("After local assignment:", spam)
do_nonlocal()
print("After nonlocal assignment:", spam)
do_global()
print("After global assignment:", spam)
scope_test()
print("In global scope:", spam)
```
在上述示例中,返回结果如下:
```
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
```