【Python】解析Python模块与包
模块
模块是非常简单的Python文件,单个Python文件就是一个模块,两个文件就是两个模块。
import语句是用来导入模块或者从模块里导入特定的类或者函数。如前面我们用过的math模块,从而可以使用sqrt函数来计算距离。
假如有一个包含Database类的database.py的模块。现有另一个模块为product.py,它需要从database.py里实例化一个Database类,然后就可以在数据库中执行相关产品查询。
import database
db = database.Database()
#数据库搜索操作
这时任何在database这个模块里面的类或者函数,都可以通过database.<something>这种激发访问。或者,也可以用from ... import语法来导入一个类。
from database import Database
db = Database()
也可以将导入的类进行重命名
from database import Database as DB # 重命名
db = DB()
也可以在一行里面导入多项,比如database还含有Query类
from database import Database, Query
但是,很多教程与经验建议不要导入模块里面所有的类,如下的写法是不采用的。
from database import *
组织模块
一个包(package)就是放在一个文件夹里的模块集合。包的名字就是文件夹的名字。我们需要做的是告诉python这个文件夹是一个包,并且把一个名为__init__.py的文件(通常是空的)放在这个文件夹里。如果我们忘记创建这个文件夹,就没法从这个文件夹里面导入那些模块。
例如在我们的工作目录里,把我们的模块放在了一个叫ecommerce(电子商务)的包里,这个目录同样包含一个main.py的文件用来启动程序。在ecommerce包里再添加一个payments的包用来管理不同的付款方式,文件夹的层次结构如下所示:
parent_directory/
main.py
ecommerce/
__init__.py
database.py
products.py
payments/
__init__.py
paypal.py
authorizenet.py

其中producs.py的有Product类
class Product:
pass
database.py有Database类
class Database:
pass
模块的导入方式有两种:绝对导入和相对导入。
绝对导入
要先给出这个模块、函数的完整路径,如在main.py需要访问produces模块中的Product类,使用使用如下的方法进行绝对导入:
import ecommerce.products
product = ecommerce.products.Product()
或者(个人比较喜欢这种方式):
from ecommerce.products import Product
product = Product()
或者:
from ecommerce import products
product = products.Product()
import语句使用点号作为分隔符来分隔包或者模块。
上述的都可以使用,如果要导入一个模块中的很多类,使用使用第三种方法,如果是指导入一个模块的一两个类,则可以使用第二种方法具体指明。
相对导入
在包(package)的情况下,如果知道父模块的名称,那么就可以使用相对导入。比如当前在products模块下工作,想从隔壁的database模块导入Database类,就可以使用相对导入:
from .database import Database # 点号表示使用当前路径的database模块
如果我们正在编辑ecommerce.payments包里的paypal模块,需要引用父包里的database模块:
from ..database import Database # 使用两个点号表示访问上层的父类
如果ecommerce有contact包,该包里有email模块,需要将该模块的sendEmail函数导入到paypal模块中,
from ..contact.email import sendEmail
数据访问权限
大部分的面向对象的编程语言都有一个“访问控制”的概念,比如私有的(private)、受保护的(protected)和公共的(public)。但python并没有这种强制规定。在技术层面上,一个类里的所有方法和属性都是公共可访问的,以下有三种形式建议不同的访问形式:
1、使用注释进行提示建议。如可以在docstring里面放一个提示来表明这个方法只是内部使用的
2、给某个属性或者方法加一个下划线的前缀,大部分python程序员会把这个解释为“这是个内部变量,使用之前要三思”
3、给某个属性或者方法添加一个双下划线的前缀,强烈建议为内部变量。访问时需要名称改编(name mangling),即在该方法或者属性前面自动加一个_<classname>的前缀(单下划线)。
一般情况下,不会使用加下划线或者双下划线的变量。
class SecretString:
''' A not-at-all secure way to store a secret string''' def __init__(self, plain_string, pass_phrase):
self.__plain_string = plain_string
self.__pass_phrase = pass_phrase def decrypt(self, pass_phrase):
''' Only show the string if the pass_phrase is correct.'''
if pass_phrase == self.__pass_phrase:
return self.__plain_string
else:
return
将上述代码存储为filename.py,然后使用python -i filename.py执行这个脚本,然后在交互的解释器里进行如下的测试:

>>> secret_string = SecretString("ACME: Top Secret", "antwerp")
>>> print(secret_string.decrypt("antwerp"))
ACME: Top Secret
>>> print(secret_string.__plain_text)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'SecretString' object has no attribute '__plain_text'
>>> print(secret_string._SecretString__plain_string)
ACME: Top Secret

从包里直接导入变量
在ecommerce包里有两个模块,一个是database.py,另一个是products.py,假设database里面有一个db变量,这个变量在很多地方都会被访问,那么我们下面的代码将可以实现用import ecommerce.db取代import ecommerce.database.db。
通过在__init__.py文件(定义目录为包),在这里文件中可以包含任意变量或者类的生命,而且它会作为这个包的一部分被我们使用。在这个例子中,如果有ecommerce/__init__.py文件里包含这么一行:
from .database import db
那么我们就可以用下面的语句,在mian.py或者其他文件访问这个db属性了:
from ecommerce import db
如果你把所有代码放在了一个单独的模块,之后又决定拆成一个包里的多个包,__init__.py文件同样对你有帮忙。
其他模块如果想要访问这个新包,__init__.py文件仍然是主要的切入点。但是在内部,代码仍然可以被组织成许多不同模块或者子包。
原文链接:
【Python】解析Python模块与包的更多相关文章
- python解析xml模块封装代码
在python中解析xml文件的模块用法,以及对模块封装的方法.原文转自:http://www.jbxue.com/article/16586.html 有如下的xml文件:<?xml vers ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- 【Python实战】模块和包导入详解(import)
1.模块(module) 1.1 模块定义 通常模块为一个.py文件,其他可作为module的文件类型还有".pyo".".pyc".".pyd&qu ...
- [19/10/16-星期三] Python中的模块和包、异常、操作文件
一.模块 # 模块(module) # 模块化,模块化指将一个完整的程序分解为一个一个小的模块 # 通过将模块组合,来搭建出一个完整的程序 # 不采用模块化,统一将所有的代码编写到一个文件中 # 采用 ...
- Python之路-Python中的模块与包
一.模块简介 在实际开发中我们不可能不用到系统的标准模块,或第三方模块. 如果想实现与时间有关的功能,就需要调用系统的time模块.如果想实现与文件和文件夹有关的操作,就需要要用到os模块. 每一个 ...
- Python中的模块与包
标准库的安装路径 在import模块的时候,python是通过系统路径找到这些模块的,我们可以将这些路径打印出来: >>> pprint.pprint(sys.path) ['', ...
- 【循序渐进学Python】10.模块和包
1.导入模块 任何Python程序都可以作为模块导入,只要Python解释器能找到我们定义的模块所在位置即可,一般来讲,在一个模块被导入时,Python解释器会按照下面的步骤进行搜索: 在当前所在目录 ...
- Python类、模块、包的区别
类 类的概念在许多语言中出现,很容易理解.它将数据和操作进行封装,以便将来的复用. 模块 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能 ...
- Python进阶之模块与包
模块 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB","S ...
- python之路模块与包
一.import加载的模块分为四个通用类别: 1 使用python编写的代码(.py文件) 2 已被编译为共享库或DLL的C或C++扩展 3 包好一组模块的包 4 使用C编写并链接到 ...
随机推荐
- 如何处理动态JSON in Go
假如要设计一个统计的json解析模块,json格式为 { "type": "用来识别不同的json数据", "msg": "嵌套的 ...
- spring和springmvc
1. 为什么使用Spring ? 1). 方便解耦,简化开发 通过Spring提供的IoC容器,可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合. 2). AOP编程的 ...
- nginx 页面加载不全的问题
在nginx的server中添加: proxy_buffer_size 2m; proxy_buffers 8 1m; proxy_busy_buffers_size 2m; 这是由于页面内容过长,默 ...
- PAT甲级1017题解——模拟排序
题目分析: 本题我第一次尝试去做的时候用的是优先队列,但是效率不仅代码量很大,而且还有测试样例过不去,很显然没有找到一个好的数据结构来解决这道题目(随着逐渐的刷PAT甲级的题会发现有时选择一个好的解题 ...
- 从Seq2seq到Attention模型到Self Attention
Seq2seq Seq2seq全名是Sequence-to-sequence,也就是从序列到序列的过程,是近年当红的模型之一.Seq2seq被广泛应用在机器翻译.聊天机器人甚至是图像生成文字等情境. ...
- Linux四剑客之awk命令
AWK详解 awk简介 awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK 的确拥有自己的语 ...
- jmeter APP接口压力测试
第一步:获取开发文档,了解接口地址和参数名 第二步:jmeter中添加需要测试的接口 a.设计APP的接口框架: b.http请求默认值设置如下: c.接口中应需要用到sign字段,加密字符串与时间戳 ...
- $.extend(obj1,obj2...,objN)小结 扩展obj1属性,有返回值,返回第一个被扩展后的对象
<script> var obj1 = { name:'liu', age:'24' } var obj2 = { name:'jinyu', sex:'m ...
- spring:过滤器和拦截器
过滤器:网络通信模型的会话层控制: 拦截器:事务处理的aop注入(生命周期监控). 对于Servlet Filter,官方文档中说的很好, 并且给出了常见的应用场景. A filter is an o ...
- Mac 上 brew 安装Tomcat
首先保证brew命令能够正常使用: 搜索tomcat是否存在:brew search tomcat 安装tomcat:brew install tomcat 检查是否安装成功:catalina -h ...