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)
|
||||
- [as](#as)
|
||||
- [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
|
||||
@@ -1155,3 +1162,193 @@ if __name__ == "__main__":
|
||||
|
||||
并且,在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