微专业 python计算生态构建 第一周

python模块和包

1.深入理解python库

库Library:一种对特定功能集合的通俗说法

  • 包含一些程序功能,通过import引入使用,对应模块和包。
  • 标准库:Standard Library,与python解释器一同安装的库。
  • 第三方库:Third-Party Library,需要额外安装的库。

模块Module:以单个文件为命名空间的代码片段

  • 模块是一个单独的.py文件,模块名就是文件名。
  • 模块本质是一个独立的、由模块名组织的命名空间。
  • 模块中可以引入其他模块,并由一些python语法来约束和管理。

包Package:由一组模块构成、有层次命名空间的程序功能

  • 包由多个模块(多个.py文件)有组织的构成。
  • 模块的组织方式构成了命名空间的层次结构。
  • 包是模块的上一级组织概念,其中可以包括子包。

模块是一切库的基础单元

  • 包由模块构成,可以理解为:包是目录,模块是.py文件。
  • 库是通俗说法,具体指python的模块和包。
  • python库的核心是模块及模块的组织方式(体现为命名空间)。

模块是一个命名空间

  • 模块对应单独的.py文件,它是一个独立的命名空间。
  • 模块内可能包含:类、函数、语句(直接可执行)、变量等元素。
  • 模块内还包括一些其他对模块进行约束和管理的语法元素。
module_var=1
class module_class:
	mc_classattr=1
	def __init__(self,mc_instattr=1):
		self.mc_instattr=mc_instattr
	def mc_fun(self):
		return "Method with a count of {}".format(self.mc_classattr)

def module_func():
	print("Module Function")

print("Module Statement")
#命名为m.py
  • 模块的调用
import m
print(m.module_var)
mc=m.module_class(99)
print(mc.mc_func())
m.module_func()
#<模块名>.<名称>
#访问模块内顶层命名空间的变量,类和函数。
'''
输出为:
Module Statement #当使用import调用m模块,m模块中的所有语句会被执行一遍
1
Method with a count of 1
Module Function
'''
from m import *
print(m.module_var)
mc=m.module_class(99)
print(mc.mc_func())
m.module_func()
输出为:
'''
Module Statement
1
Method with a count of 1
Module Function
'''
  • 我们在名字前增加一个下划线
_module_var=1 #加一个下划线
class module_class:
	mc_classattr=1
	def __init__(self,mc_instattr=1):
		self.mc_instattr=mc_instattr
	def mc_fun(self):
		return "Method with a count of {}".format(self.mc_classattr)

def _module_func():
	print("Module Function")

print("Module Statement")
#命名为m.py
'''
此时我们用import m的方式依然可以调用
但是当我们用from m import *程序运行会报错
'''

模块是一个命名空间

  • 模块中语句:在import时一次性执行。
  • 模块内的变量、类和函数:在import时采用<模块名>方式可访问。
  • 单下划线的顶层命名元素:不会在from … import * 时被导入。

包是一个有层次的命名空间

  • 每个包需要包含一个__init__.py文件表达包的组织。
  • _ _ init _ _.py可以是空文件,即,文件存在即可。
  • 每个包可以嵌套包含更多子包。
  • 通过包的组织可以形成由英文句号(.)分隔的层次化命名空间。
  • _ _ init _ _.py用来构成包的定义,区分于包含.py文件的普通目录。
  • 包、子包和模块可以用import 进行导入或单独导入。

模块的名称属性

名称属性:表达模块名称的预定义变量

属性描述
_ _name _ _模块或包的名字,例:m. _ _ name _ _
def _module_func():
	print("Module Function")

module_var=1
print("Module Statement")
print(__name__)
'''
Module Statement
__main__
'''
import m
'''
输出为:
Module Statement
m
'''
  • 当程序以脚本方式直接执行时,_ name _的值为‘ _ _ main _ _’。
  • 当程序以模块方式被引用时,_ name _ 的值为模块名称。
  • 作用:区分程序以何种方式执行。
def _module_func():
	print("Module Function")
	
if __name__=="__main__":
	module_var=1
	print("Module Statement")
	print(__name__)
'''
Module Statement
__main__
'''
import m
'''
无输出
'''

if _ _ name _ _ == ’ _ _ main _ _ ’ :

  • 当程序以脚本方式执行时,后续代码可以执行,否则不执行。
  • 作用1:作为模块主体功能的单元测试部分。
  • 作用2:作为模块内部保留的额外功能部分。

模块和包的构建

模块的构建

  • 功能闭包:单一.py文件实现单一且完整的功能。
  • 抽象适度:用函数或类进行抽象,结合功能选择合适抽象。
  • 操作闭包:模块无顶层可执行语句,导入时无输出。

模块的构建原则

  • 功能闭包:功能定义要清晰、设计要合理(紧耦合vs松耦合)。
  • 抽象适度:采用类或函数,尽量选择一种;多种也无妨。
  • 操作闭包:采用 _ _ name _ _ ,无全局可执行语句,尽量无全局变量。
"这是模块描述" #第一行增加描述
class module_class:
	mc_classattr=1
	def __init__(self,mc_instattr=1):
		self.mc_instattr=mc_instattr
	def mc_func(self):
		return "Method with a count of {}".format(self.mc_classattr)

if __name__='__main__':
	import sys
	mc=module_class(sys.argv[1])
	print("Module Statement") #顶层功能的引用放在__name__后
#dir()函数:以列表形式返回模块所使用的命名。
import m
print(dir(m))

包的构建

  • 常规包:Regular Packages,通过 _ _ init _ _.py对文件和目录组织形成的包。
  • 命名空间包:Namespace Packages,由更分散子包组成的包。
    • 子包的位置可以再文件系统中不连续。
    • 子包可以是压缩文件或网络连接或其他系统资源。

常规包

  • 连续目录空间表达的、有层次的命名空间。
  • 每个目录中包含一个 _ _ init _ _ .py,可以是空文件。
  • 当包/子包被导入时,对应目录的 _ _ init _ _.py文件将被执行。
  • 每个包仅被导入一次,且包导入按照层次结构进行。
  • 直接导入包不行,需要进行到模块层次。(import pkg.pkg1包)
  • from … import …直接导入具体模块,可以简化调用时命名空间表达。
    (但是from … import * 需要额外代码的编写。)

_ _ all _ _ 属性

  • from…import * 形式需要在 _ _ init _ _.py文件中增加 _ _ all _ _属性赋值。
  • _ _all _ _ 需要被赋值为列表对象,包含当前包下所有希望被导入的模块名称。
  • _ _ all _ _ 用来辅助导入模块,但不能辅助导入列表。
__all__=['m1','m2']
 #在__init__.py中写入,再使用from ... import *就可以了。

命名空间包

命名空间包:表达命名空间层次结构的一种逻辑包形式

  • 命名空间中各部分可以在不同的文件系统位置。
  • 命名空间中各个子包并不包含__init__.py文件(普通目录!)
  • python解释器通过sys.path变量来隐式维护命名空间包。
import sys
sys.path+=['project1','project2']

import pkg1.m1
import pkg1.m3

pkg1.m1.mecho(123)
pkg1.m3.mecho('python')

print(pkg1.__path__)

sys.path:指定搜索路径的字符串列表

  • 指定import时搜索模块或包的路径列表,路径是相对或绝对路径。
  • sys.path是一个列表类型,可以sys.path.append(p)增加新路径p。
  • 载入后,根据其中包的名称和层次结构自然组成了命名空间包。

_ _ path _ _ 属性

  • 记录了某个包(命名空间)的绝对或相对路径,列表类型。
  • 常规包:路径是单一的,列表中只有一个元素。
  • 命名空间包:路径是多元的,列表中可能有多个元素。

import系统:扩展命名空间及功能的方法

  • 构成:import保留字、_ import _()函数和importlib标准库
  • 步骤:模块的查找、模块的加载
  • 价值:import系统是python代码复用和命名空间管理的精髓。
  • import保留字:调用 _ import _进行模块查找,以及模块的加载。
  • _ import _ ()函数:模块的查找,建立模块对象。
  • importlib标准库:与import系统相关的丰富API。
模块的加载
模块的查找
模块对象
ImportError
当前命名空间

万物皆对象:模块被导入后成为了对象

  • 模块的对象形式:模块在程序中使用都是以对象形式体现的。
  • 类似类对象,模块对象只有一个。
  • 模块对象生成时,模块中代码会被执行,因此会有类对象产生。

模块的查找
查找路径:1.sys.modules

  • 第一步查找sys.modules,之前被引入模块的缓存(cache)。
  • sys.modules是一个字典,<模块名/对象引用>:<加载路径>。
  • 如果模块不再sys.modules中,则进入下一步。

查找路径:2.查找策略

  • 用户通过import钩子扩展的查找模式。
  • 内置模块的路径。
  • sys.path(列表变量)提供的加载路径,可以是zip文件或URL。

import钩子:import hook

  • 扩展查找模块的方式:meta_path方式和import路径方式。
  • meta_path:将查找方法增加到sys.meta_path列表变量。
  • import路径:将查找方法注册到sys.path_hooks列表变量。

建立模块对象的过程

  • 找到模块后,如果模块对象存在,则使用现有模块对象。
  • 创建一个新的模块对象,将其加入sys.modules。
  • 在程序当前命名空间执行模块代码。
  • 创建对象:importlib.abc.loader.create_module()
  • 执行对象:importlib.abc.loader.exec_module()

模块对象的命名空间

  • 模块的命名空间与引用位置有直接关系。
  • 如果引用在文件顶层,则使用文件顶层命名空间访问模块。
  • 如果引用在非顶层,则使用局部命名空间访问模块。

import的三种使用方式

  • import <模块名>
  • from <模块名> import <类、函数名、*>
  • import <模块名> as <别名>

import <模块名>

  • 当前命名空间下的一个子命名空间。
  • 成功加载后,产生一个与<模块名>同名的<模块对象名>。
  • 实际上:<模块对象名>.<子命名空间内元素>方式访问。

from <模块名> import <类、函数、*>

  • 将导入元素加载到当前命名空间下。
  • 成功加载后,产生类对象或函数对象,覆盖同名对象。
  • 实际上:<类对象名>或<函数对象名>方式访问。

import <模块名> as <别名>

  • 当前命名空间下的一个子命名空间。
  • 成功加载后,产生一个与<别名>同名的<模块对象名>。
  • 实际上:<模块对象>.<子命名空间内元素>方式访问。

python第三方库的发布

发布前的准备

  • PyPI:python package index,用来登记第三方库信息。
  • Github、bitbucket:存储第三方库源代码及文档。
  • 目标:通过pip进行安装和管理、源代码和文档网络可管理。

一些基本概念

  • 项目project:pypi上一组发布和文件的统称。
  • 发布release:项目的一个特定版本,每个发布有一个确定的版本号。
  • 文件file:即package,一次发布包含的具体文件。
setuptools
twine
.py源代码
一种分发形式
pypi:pypi.org
  • 更新setuptools、wheel、twine工具。

  • 注册pypi账户。

  • 第一步:整理目录结构。

  • 第二部:创建其他文件(setup.py:配置发布信息的文件,很重要。README.md:markdown格式的说明文件。LICENSE:版权声明文件。)

  • 第三部:执行打包命令(python setup.py sdist bdist_wheel)

  • 第四部:执行发布命令(twine upload dist/*)

  • 打包发布:对文件整理打包后进行发布。

  • 源发布:发布源代码的方式。

  • 可执行发布:发布编译后可执行代码的方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值