diff --git a/python/py.md b/python/py.md index 50623c6..4977e2e 100644 --- a/python/py.md +++ b/python/py.md @@ -75,6 +75,13 @@ - [finditer](#finditer) - [面向对象](#面向对象) - [命名空间](#命名空间) + - [module](#module-1) + - [module name](#module-name) + - [module statements](#module-statements) + - [when statements will be executed](#when-statements-will-be-executed) + - [from ... import ...](#from--import--1) + - [as](#as) + - [execute module as script](#execute-module-as-script) # Python @@ -1042,5 +1049,109 @@ namespace的示例有: > 在某种程度上来说,对象中的attributes也构成了一个命名空间 +## module +python支持将文件内容拆分到多个文件中,将function definition放置到文件中后,在`其他文件`或`interactive instance`中可以针对fucntion definition进行导入。 +放置function definition的文件被称之为`module`,通常用来定义公共方法。 + +### module name +module为包含python definition和statements的文件。file name由module name和`.py`后缀组成。在module中,module的名称可以通过全局变量名`__name__`进行访问。 + +如果在文件`fibo.py`中定义如下内容: +```py +# Fibonacci numbers module + +def fib(n): + """Write Fibonacci series up to n.""" + a, b = 0, 1 + while a < n: + print(a, end=' ') + a, b = b, a+b + print() + +def fib2(n): + """Return Fibonacci series up to n.""" + result = [] + a, b = 0, 1 + while a < n: + result.append(a) + a, b = b, a+b + return result +``` +那么`fibo`module中的内容可以通过如下方式进行导入 +```py +import fibo +``` +上述导入并不会将定义在`fibo`module中的function name直接添加到当前的命名空间,其只是将module name`fibo`添加到了命名空间,可以通过module name访问module中定义的内容: +```py +fibo.fib(1000) + +fibo.fib2(100) + +fibo.__name__ +``` +### module statements +在module中除了可以包含function definition外,还可以包含可执行statements。该可执行statements用于对module进行初始化。 + +#### when statements will be executed +module中的statements只会在`第一次该module被导入`时执行。(如果module文件其本身被执行,而非作为依赖被其他文件导入,那么module中的statements也同样会被执行) + +每个module都拥有其自己的private namespace,并且对于定义在module中的所有方法而言,`private module`既是`global namespace`。故而,作为module的开发者而言,其可以自由的使用global variables,而不用担心其global variables名称和module使用者定义的global variables发生冲突。 + +如果想要访问在module中定义的global variables,可以使用`modname.itemname`的方式。 + +通常而言,对于module的import被放置在文件的最外层最开始的部分,`但这并非是必须的`。在文件最外层被导入的module,其module name会被添加到当前文件的module glboal namespace中。 + +#### from ... import ... +import还存在一个变体,可以从module中直接导入name,而不是导入module后通过module name访问module中内容: +```py +from fibo import fib, fib2 +fib(500) +``` +在上述示例中,`fibo`并没有被引入到当前文件的global namespace中。 + +除此之外,还可以导入module中所有的name +```py +from fibo import * +fib(500) +``` +同样的,`fibo`也不会被导入到当前global namespace中。 + +上述`from fibo import *`语句会导入`fibo`module中定义的所有name,但是以下划线`_`开头的名称除外。 + +通常情况下,不要使用`from fibo import *`来进行导入,因为其引入的name是不确定的,可能会覆盖你所定义的部分内容。 + +#### as +在对其他module执行import操作时,可以通过as来进行重命名 + +```py +import fibo as fib +fib.fib(500) +``` +上述示例中,`fib`的名称将会绑定到module `fibo`。 + +```py +from fibo import fib as fibonacci +fibonacci(500) +``` + +### execute module as script +当想要将module作为script执行时,可以使用如下命令: +```bash +python fibo.py +``` + +上述`将module作为script执行的命令`,和`导入module时对module进行执行`的行为实际上是一致的,唯一区别如下: +- `module作为script执行`: `__name__`值为`__main__` +- `module被导入`: `__name__`值为`module name` + +故而,在module中包含如下代码 +```py +if __name__ == "__main__": + import sys + fib(int(sys.argv[1])) +``` +可以使module既可作为module被导入,也可以作为可执行的脚本,其中该代码块只会在module作为main file时才会被执行。 + +并且,在module被导入时,`sys`并不会被导入。