专业编程基础技术教程

网站首页 > 基础教程 正文

ScalersTalk成长会Python小组第12周学习笔记

ccvgpt 2025-03-25 11:23:29 基础教程 21 ℃

Scalers点评:在2015年,ScalersTalk成长会完成Python小组完成了《Python核心编程》第1轮的学习。到2016年,我们开始第二轮的学习,并且将重点放在章节的习题上。Python小组是成长会内部小组,如果你想和我们一起学习Python,你需要是成长会成员,并且完成相关进群任务。

我们的节奏是行动是一周一章学到位,章节习题都会一个一个过。通过到位地执行,达到实质性的提升。

ScalersTalk成长会Python小组第12周学习笔记

往期日志:

本周学习情况

本周(20160404-20160410)学习第十二章,章节内容为《模块》。本周复盘主持人为 Rainmaker 。

本章主要内容

本章主要讲述了:

什么是模块(What Are Modules)

模块与文件(Modules and Files)

命名空间(Namespaces)

导入模块(Importing Modules)

导入模块属性(Importing Module Attributes)

用于模块的内建函数(Module Built-in Functions)

包(Packages)

模块的其它特性(Other Features of Modules)

本章主要知识点

12.1 What Are Modules?

可以被分享(be shared)的自我包含(self-contained)的有条理(organized)的 Python 代码片段(piece)。

自我包含是指:它需要的东西它自己都有。可以理解为独立且完整。

12.2 Modules and Files

我们通过使用模块去有逻辑的管理 Python 代码,使用文件(file)在物理层面上(physically)管理模块。

比如一个文件的文件名是 milk.py,它的模块名就是milk

和其他导入(import)类(class)的语言不同,在 Python 中我们导入模块或模块属性(attribute)。

12.2.1 Module Namespaces

命名空间(namespace)的基本概念是:一个名称到对象的映射集合。(an individual set of mappings from names to objects)

通常是 module.attribute这样的格式。这种完整授权名称(fully qualified name)避免了名称冲突。

12.2.2 Search Path and Path Search

// 路径(path)与目录(directory)的区别

  • http://unix.stackexchange.com/questions/131561/what-is-the-difference-between-path-and-directory

  • http://kb.winzip.com/kb/entry/284/

  • 总结:目录是“文件夹(folder)”,是你所在的地方;路径是对象的位置,你按照路径到达对象,路径是相对的。

    我的理解:搜索的路径(search path)是名词,路径的搜索(path search)是动词。

    默认的搜索的路径是在编译(compilation)或安装(installation)时指定的。可以在这两个地方中的任意一个对搜索的路径进行修改。

  • 我们启动 Python 的 shell 或命令行(command-line)的环境变量 PYTHONPATH 。

  • PYTHONPATH 里包含着一些用冒号分隔的目录的路径(directory path)。

  • 如果要使用 PYTHONPATH ,请在启动解释器(interpreter)或运行 PYTHON 脚本(script)之前设置(set)或更新(update) PYTHONPATH。

  • 启动解释器后,sys 模块的 sys.path变量。

  • sys.path.append自动添加至列表末尾,如有特殊需要可以用insert

  • sys.path是一个列表,包含多个字符串形式的目录。把需要导入的模块的目录添加到sys.path中。

  • 如果你的模块有很多拷贝件(在不同的目录里),解释器会使用按照搜索的路径的顺序找到的第一个。可以通过 sys.modules查看当前导入的模块及其物理位置。

  • site-packages里放着第三方包/模块。

12.3 Namespaces

给命名空间添加一个名称时,该标识符绑定了该对象(该对象的 reference count 加1)。

《Python 语言参考》定义:改变一个名称的映射叫重新绑定(rebinding),删除一个名称叫解除绑定(unbinding)。

执行期间有两个或三个活动的命名空间:局部(local)命名空间、全局(global)命名空间、内建(built-ins)命名空间。其中局部命名空间在执行期间不断变动。

从命名空间中对名称的访问取决于它们的加载顺序,或者系统加载命名空间的顺序。

Python 解释器先加载由 __builtins__ 模块内名称构成的内建命名空间,然后是全局命名空间。这样就有两个活动的命名空间了。

CORE NOTE: __builtins__ versus __builtin__

__builtin__ 模块包含内建函数(function)、异常(exception)和其它属性。

标准 Python 执行环境下,__builtins__ 包含了 __builtin__ 里的所有名称。曾经有个限制执行(restricted execution)模式后来没了。

运行时调用(call)一个函数,局部命名空间就出现了。

12.3.1 Namespaces versus Variable Scope

从变量作用域来看,名称A要么是局部的,要么是全局的。从命名空间来看,全局存在一个名称A,局部也可以存在一个名称A,然而在执行期间,局部的名称A把全局的名称A覆盖(override)了。

所以说每个命名空间都是自我包含的,但从变量作用域的角度,一个名称要么局部要么全局,不可能两边都有。

12.3.2 Name Lookup, Scoping, and Overriding

我们访问一个属性时,解释器就得在这三个命名空间里找到它。局部,全局,内建,依次排查,还没找到就产生错误。

局部命名空间找到的名称会遮住全局和内建命名空间里对应的对象。

12.3.3 Namespaces for Free!

使用点(.)标记法给已知模块添加属性。

12.4 Importing Modules

12.4.1 The import Statement

导入模块的语法有两种。

  • import module1

    import module2

    import moduleN

  • import module1[, module2[,… moduleN]]

    • 这种可读性差。

  • 这两种在性能上没有区别,推荐使用第一种。

CORE STYLE: Module ordering for import statements

  • 建议先导入需要的所有模块再写当前模块的其它内容。

  • 模块导入应遵循此顺序:(组与组之间空行隔开)

    • Python 标准库模块(Python Standard Library modules)

    • Python 第三方模块(Python third party modules)

    • 应用程序自定义模块(Application-specific modules)

作用域法则(scoping rules)适用:

  • 在最开始导入的模块作用域为全局,在函数中导入的模块作用域为局部。

第一次导入一个模块时,该模块被加载并运行。

12.4.2 The from-import Statement

把特定的模块的元素(element)导入到自己的模块里(当前命名空间里)。

语法是:from module import name1[, name2[,… nameN]]

12.4.3 Multi-Line Import

from module1 import aaa, bbb, ccc, ddd

from module1 import eee, fff, ggg

  • Python 2.4 开始可用。

推荐用法为:

 from module1 import (aaa, bbb, ccc, ddd, eee, fff, ggg)

不推荐使用 from module import *

12.4.4 Extended Import Statement (as)

import module as mo

from module import whaaa as wha

Python 2.0 开始有这个特性,2.6 开始 as 正式成为一个关键字(keyword)。

12.5 Features of Module Import

12.5.1 Module “Excuted” When Loaded

顶层(the top-level portion)代码在加载时被执行,通常包括全局变量、类、函数的声明。如果有检查 __name__ 的操作,也会执行。

  • 比如 if __name__ = “__main__”:

    • http://stackoverflow.com/questions/419163/what-does-if-name-main-do

尽量把代码封装到函数里。

只把函数和(或)模块定义放在顶层。

12.5.2 Importing versus Loading

加载(load)只在第一次导入(import)时发生。

12.5.3 Names Imported into Current Namespace

from module import var,然后我们要用“var”时直接写var就可以,不用写 module.var

CORE STYLE: Restrict your use of “from module import *”

  • 不用的原因:“污染”了当前命名空间,可能覆盖当前命名空间的某些名称。

  • 用的原因:当这个模块变量太多或这个模块名称太长时。

  • 只建议在这两种情况下使用:

    • 用于 Tkinter 模块、Numpy 模块及 socket 模块。

    • 在交互解释器中。这样可以少打点儿字。

12.5.4 Names Imported into Importer’s Scope

只导入名称的副作用是,这些名称会成为局部命名空间的一部分。这可能遮蔽(hide)或覆盖一个已存在的或内建的同名对象。这只对当前(局部命名空间)有影响。

  • 可能属于浅拷贝?

12.5.5 Back to the __future__

在低版本里体验高版本的特性,为以后的适配做准备。

正确语法是:from __future__ import new_future

错误语法:import __future__ 别这样,没用。

12.5.6 Warning Framework

12.5.7 Importing Modules from ZIP Files

ZIP文件可以作为目录的一部分。

/tmp/yolk.zip/lib/ 也是可以的。

12.5.8 “New” Import Hooks

12.6 Module Built-in Functions

12.6.1 __import__

据说用于动态的导入。

语法:__import__(module_name[, globals[, locals[, fromlist]]]

例:sys = __import__(‘sys’)

12.6.2 globals and locals

globalslocals分别以字典(dictionary)的形式在调用的地方返回全局命名空间和局部命名空间。所以,当在全局命名空间调用这两个函数时,返回的内容是一样的。

12.6.3 reload

重新导入一个已导入的模块,此时该模块将像第一次导入一样加载、执行。

已导入模块必须是完全导入,不能是 from-import 。

正确语法:reload(sys)

错误示范:reload(‘sys’)

12.7 Packages

有层次(hierarchical)的文件目录结构。用于定义一个由模块、子包(subpackage)组成的 Python 应用环境。

12.7.1 Directory Structure

语法:import
package.subpackage.module.attribute

调用某个属性也是像这样用点(.)标记法。

语法:from xxx.xxx import xxx.xxx

每个包目录中的 __init__.py 是初始化文件。

12.7.2 Using from-import with Packages

语法:from xxx.xxx import *

这个语句依靠操作系统的文件系统来决定导入哪些文件。

12.7.3 Absolute Import

由于导入的的名称可能与已有的标准库模块名称冲突,所以从 Python2.7开始要求绝对导入。

  • 我的理解就是全名导入。

12.7.4 Relative Import

一种缩写形式的相对导入。因为 import 语句永远是绝对导入,所以只用于 from-import 语句。

例如:from aaa.bbb.ccc import ddd

可写为:from ..ccc import ddd

12.8 Other Features of Modules

12.8.1 Auto-Loaded Modules

Python 解释器在标准模式下启动时会自动加载一些为系统所用的模块。如 __builtin__ 模块、__builtins__ 模块。

变量 sys.modules是一个关于当前解释器完整且成功加载的模块的字典,键(key)是该模块名,值(value)是该模块的位置,该模块从那里导入过来。

12.8.2 Preventing Attribute Import

不想让某个属性在 from module import *时被导入,给该属性命名时可以“_”开头。

导入了整个模块或显式(explicitly)导入该属性仍会正常导入。如 import foo._bar

12.8.3 Case_Insensitive Import

12.8.4 Source Code Encoding

# -*- coding: UTF-8 -*-

12.8.5 Import Cycles

12.8.6 Module Execution

有很多方法去执行一个模块,比如在命令行或 shell 里使用,execfile ,模块导入等等。第14章会讲。

12.9 Related Modules

一些相关模块的介绍。

12.10 Exercises

12-1

PathSearch versus SearchPath. What is the difference between a path search and a search path?

搜索的路径(search path)是名词,通常指一个或一些目录(directory),路径的搜索(path search)是动词,通常指查找某个文件这一行为。书中说,路径的搜索是:

“This is the procedure of checking “predefined areas” of the file system to look for your mymodule.py file in order to load the mymodule module.”

其中“预定义区域(predefined areas)”就属于搜索的路径。

12-2

Importing Attributes. Assume you have a function called foo in your module mymodule.

(a) What are the two ways of importing this function into your namespace for invocation?

(b) What are the namespace implications when choosing one over the other?

(a)

第一种:先 import mymodule然后再mymodule.foo

第二种:from mymodule import foo

(b)

第一种以 module.attribute的形式把 mymodule 模块里的所有名称都导入到当前的命名空间。

第二种只把 mymodule 模块中的 foo 导入到当前的命名空间。

12-3

Importing. What are the differences between using “import module” and “from module import ”?

from module import *把 module 模块里所有名称都导入到当前的命名空间,使用时直呼其名就可以了。

12-4

Namespaces versus Variable Scope. How are namespaces and variable scopes different from each other?

每个命名空间都是独立且完整的,但从变量作用域的角度,一个名称要么局部要么全局,不可能两边都有。

12-5

Using __import__.

(a) Use __import__ to import a module into your namespace. What is the correct syntax you finally used to get it working?

(b) Same as above, but use __import__ to import only specific names from modules.

(a)sys = __import__('sys')

(b)书上语法是__import__(module_name[, globals[, locals[, fromlist]]])

这是我的尝试:

>>> foo = __import__('mymodule'[, globals[, locals[, [foo]]]]) File "", line 1 foo = __import__('mymodule'[, globals[, locals[, [foo]]]]) ^ SyntaxError: invalid syntax >>> foo = __import__('mymodule', [foo]) >>>foo  >>>

12-6

Extended Import. Create a new function called importAs.This function will import a module into your namespace, but with a name you specify, not its original name. For example, calling newname = importAs(‘mymodule’) will import the module mymodule, but the module and all its elements are accessible only as newname or newname.attr. This is the exact functionality provided by the new extended import syntax introduced in Python 2.0.

def importAs(module_name): return __import__('module_name')
    ScalersTalkID:scalerstalk

    本微信公众号作者Scalers,游走在口译世界的IT从业者。微信公众号ScalersTalk,网站ScalersTalk.com,口译100小时训练计划群C 456036104


    成长会是由Scalers发起的面向成长、实践行动,且凝聚了来自全球各地各行各业从业者的社群。有意入会者请和Scalers直接联系,我和其他会员会和你直接交流关于成长行动等各方面的经验教训。2016年成长会持续招募中,参见做能说会写的持续行动者:ScalersTalk成长会2016年会员计划介绍(2016.3更新)

最近发表
标签列表