doc: 阅读python module文档
This commit is contained in:
197
python/py.md
197
python/py.md
@@ -82,6 +82,13 @@
|
|||||||
- [from ... import ...](#from--import--1)
|
- [from ... import ...](#from--import--1)
|
||||||
- [as](#as)
|
- [as](#as)
|
||||||
- [execute module as script](#execute-module-as-script)
|
- [execute module as script](#execute-module-as-script)
|
||||||
|
- [module search path](#module-search-path-1)
|
||||||
|
- [`sys.path`初始化](#syspath初始化)
|
||||||
|
- [standard module](#standard-module)
|
||||||
|
- [dir function](#dir-function)
|
||||||
|
- [packages](#packages)
|
||||||
|
- [import \* from package](#import--from-package)
|
||||||
|
- [包内部相互引用](#包内部相互引用)
|
||||||
|
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
@@ -1155,3 +1162,193 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
并且,在module被导入时,`sys`并不会被导入。
|
并且,在module被导入时,`sys`并不会被导入。
|
||||||
|
|
||||||
|
### module search path
|
||||||
|
当module名为`spam`的module被导入时,interpreter会按照如下顺序来进行查找:
|
||||||
|
1. 首先,interpreter会从built-in module中查找`spam`
|
||||||
|
2. 如果步骤1没有查询到,其会在`sys.path`变量定义的路径中查找名为`spam.py`的文件
|
||||||
|
|
||||||
|
#### `sys.path`初始化
|
||||||
|
在python启动时,其会初始化module search path,初始化后的module search path可以通过`sys.path`来进行访问。
|
||||||
|
|
||||||
|
在`sys.path`中,组成如下:
|
||||||
|
- `sys.path`中第一条entry是包含input script的目录(如果存在input script)
|
||||||
|
- 若未指定input script,如`运行交互式shell`、`运行-c command`、`运行-m module`时,`sys.path`的第一条entry则是当前目录
|
||||||
|
- `PYTHONPATH`环境变量中定义的路径也会被添加到search path中
|
||||||
|
- 包含`standard python modules及其依赖的拓展modules`的路径也会别添加到module search path中
|
||||||
|
- 拓展modules在windows平台中后缀名为`.pyd`,在其他平台中后缀名为`.so`
|
||||||
|
- 其中,`standard python modules`是平台无关的,被称为`prefix`
|
||||||
|
- `extension modules`则是平台相关的,被称为`exec_prefix`
|
||||||
|
|
||||||
|
|
||||||
|
> python支持通过`-c`来直接运行python命令,示例如下
|
||||||
|
> ```shell
|
||||||
|
> python -c 'print(1+22*33)'
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> python还支持通过`-m`来直接运行module,示例如下
|
||||||
|
> ```bash
|
||||||
|
> echo '{"name":"John","age":30}' | python -m json.tool
|
||||||
|
> ```
|
||||||
|
|
||||||
|
> 部分系统支持symlinks,故而包含input script的目录路径会在input script的symlink被follow之后才进行计算。故而,`包含symlink`的目录并不会被添加到sys.path中
|
||||||
|
|
||||||
|
在`sys.path`被初始化之后,python程序可以对`sys.path`进行修改。
|
||||||
|
|
||||||
|
在`sys.path`中,包含被运行文件的目录路径被放在了`sys.path`中最开始的位置,代表如果运行文件路径中如果存在和`standard library module`相同名称的文件,那么运行文件路径下的同名文件将会覆盖`standard library module`。
|
||||||
|
|
||||||
|
### standard module
|
||||||
|
python附带了一个包含standard modules的library。`standard modules`中部分modules是内置在interpreter中的,built modules中的内容可能并不是语言核心操作的一部分,但是能够提供对操作系统的访问,例如系统调用等。
|
||||||
|
|
||||||
|
built-in modules中的module在不同平台是可选的,例如`winreg` module只存在于windows平台。但是,`sys`module在所有平台的python interpreter中都包含。
|
||||||
|
|
||||||
|
### dir function
|
||||||
|
内置的`dir()`方法会查看在module中定义了哪些名称,其返回了一个sorted string list:
|
||||||
|
```bash
|
||||||
|
>>>import fibo, sys
|
||||||
|
>>>dir(fibo)
|
||||||
|
['__name__', 'fib', 'fib2']
|
||||||
|
>>>dir(sys)
|
||||||
|
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
|
||||||
|
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
|
||||||
|
'__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
|
||||||
|
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
|
||||||
|
'_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
|
||||||
|
'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
|
||||||
|
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
|
||||||
|
'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
|
||||||
|
'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
|
||||||
|
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
|
||||||
|
'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
|
||||||
|
'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
|
||||||
|
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
|
||||||
|
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
|
||||||
|
'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
|
||||||
|
'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
|
||||||
|
'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
|
||||||
|
'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
|
||||||
|
'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
|
||||||
|
'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
|
||||||
|
'warnoptions']
|
||||||
|
```
|
||||||
|
当没有为`dir()`方法传递参数时,`dir()`方法会列出当前已经定义的名称:
|
||||||
|
```python
|
||||||
|
>>> a = [1, 2, 3, 4, 5]
|
||||||
|
>>> import fibo
|
||||||
|
>>> fib = fibo.fib
|
||||||
|
>>> dir()
|
||||||
|
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
|
||||||
|
```
|
||||||
|
其列出的名称中包含所有类型:变量、module、function等
|
||||||
|
|
||||||
|
`dir`方法并不会列出内置的方法和变量,如果想要查看那些,可以使用`dir(builtins)`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
import builtins
|
||||||
|
dir(builtins)
|
||||||
|
```
|
||||||
|
### packages
|
||||||
|
packge是一种结构化python modules命名空间的方法,其使用了`dotted module names`。例如,module name为`A.B`其代表的是位于package A下的submodule B。
|
||||||
|
|
||||||
|
就像module可以使module的开发者们不用担心使用了和其他module中一样的变量/函数名一样,dotted module name可以令module的开发者不用担心使用了和其他module相同的module name。
|
||||||
|
|
||||||
|
如果,你要定义一系列的modules统一处理不同格式的sound files和sound data,可以采用如下的package结构:
|
||||||
|
```
|
||||||
|
sound/ Top-level package
|
||||||
|
__init__.py Initialize the sound package
|
||||||
|
formats/ Subpackage for file format conversions
|
||||||
|
__init__.py
|
||||||
|
wavread.py
|
||||||
|
wavwrite.py
|
||||||
|
aiffread.py
|
||||||
|
aiffwrite.py
|
||||||
|
auread.py
|
||||||
|
auwrite.py
|
||||||
|
...
|
||||||
|
effects/ Subpackage for sound effects
|
||||||
|
__init__.py
|
||||||
|
echo.py
|
||||||
|
surround.py
|
||||||
|
reverse.py
|
||||||
|
...
|
||||||
|
filters/ Subpackage for filters
|
||||||
|
__init__.py
|
||||||
|
equalizer.py
|
||||||
|
vocoder.py
|
||||||
|
karaoke.py
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
当对package进行导入时,python会从`sys.path`中查询package的子目录。
|
||||||
|
|
||||||
|
其中,`__init__.py`文件用于`让python将该目录看作是package`。`__init__.py`文件可以是空文件,但是`也可以包含对package进行初始化的代码`或`设置__all__变量`。
|
||||||
|
|
||||||
|
在使用package中,可以单独导入package中的module:
|
||||||
|
```py
|
||||||
|
import sound.effects.echo
|
||||||
|
```
|
||||||
|
上述示例中导入了`sound.effects.echo`module,在对module进行使用时,必须采用如下方式指定mdoule的fullname:
|
||||||
|
```py
|
||||||
|
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
|
||||||
|
```
|
||||||
|
另一种可选的导入方式如下:
|
||||||
|
```py
|
||||||
|
from sound.effects import echo
|
||||||
|
```
|
||||||
|
在使用module时,只需要指定echo即可
|
||||||
|
```py
|
||||||
|
echo.echofilter(input, output, delay=0.7, atten=4)
|
||||||
|
```
|
||||||
|
同时,也可以直接导入module中的方法:
|
||||||
|
```py
|
||||||
|
from sound.effects.echo import echofilter
|
||||||
|
|
||||||
|
echofilter(input, output, delay=0.7, atten=4)
|
||||||
|
```
|
||||||
|
|
||||||
|
在使用`import item.subitem.subsubitem`这类语法时,除了最后的item外,其余item必须都要是package,最后的item可以是package或module,但不能是module中的内容。
|
||||||
|
|
||||||
|
#### import * from package
|
||||||
|
在对package执行`import *`的语法时,其导入行为准许如下规范:
|
||||||
|
- 如果package的`__init__.py`文件中定义了`__all__`变量,其将认为`__all__`中定义了所有应该被`import *`所导入的module name
|
||||||
|
|
||||||
|
故而,package的开发者应当负责在package版本迭代时将`__all__`进行更新;当然,开发者页可以决定不对`import *`进行支持,不定义`__all__`。
|
||||||
|
|
||||||
|
示例如下,`sound/effects/__init__.py`中可能包含如下内容:
|
||||||
|
```py
|
||||||
|
__all__ = ["echo", "surround", "reverse"]
|
||||||
|
```
|
||||||
|
其代表`from sound.effect import *`将会导入`echo, surround, reverse`三个module。
|
||||||
|
|
||||||
|
注意,本地定义的名称可能会遮挡submodules。例如,如果在`sound/effects/__init__.py`中定义了一个reverse函数,那么`from sound.effects import *`将只会导入`echo, surround`两个module。
|
||||||
|
```py
|
||||||
|
__all__ = [
|
||||||
|
"echo", # refers to the 'echo.py' file
|
||||||
|
"surround", # refers to the 'surround.py' file
|
||||||
|
"reverse", # !!! refers to the 'reverse' function now !!!
|
||||||
|
]
|
||||||
|
|
||||||
|
def reverse(msg: str): # <-- this name shadows the 'reverse.py' submodule
|
||||||
|
return msg[::-1] # in the case of a 'from sound.effects import *'
|
||||||
|
```
|
||||||
|
|
||||||
|
如果在`__init__.py`中没有定义`__all__`,那么`from sound.effects import *`只会导入`__init__.py`中的其他定义内容,示例如下:
|
||||||
|
```py
|
||||||
|
import sound.effects.echo
|
||||||
|
import sound.effects.surround
|
||||||
|
from sound.effects import *
|
||||||
|
```
|
||||||
|
|
||||||
|
### 包内部相互引用
|
||||||
|
在同一个包中,不同subpackage中的module可以对彼此进行引用。引用支持绝对路径和相对路径,例如,`sound.filters.vocoder`在对`sound.effects`中定义的包进行import时,可以采用如下方式:
|
||||||
|
- 绝对路径:`from sound.effects import echo`
|
||||||
|
- 相对路径:`from ..effects import echo`
|
||||||
|
|
||||||
|
在使用相对路径的导入时,示例如下:
|
||||||
|
当从`surround`执行相对路径导入时,可以执行如下形式的导入
|
||||||
|
```py
|
||||||
|
from . import echo # 位于相同的subpackage中
|
||||||
|
from .. import formats # 访问../formats
|
||||||
|
from ..filters import equalizer # 访问../filters中的equalizer
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user