python3-cookbook笔记:第十章 模块与包
python3-cookbook中每个小节以问题、解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构、函数、类等特性在某类问题上如何更好地使用。这本书对于加深Python3的理解和提升Python编程能力的都有显著帮助,特别是对怎么提高Python程序的性能会有很好的帮助,如果有时间的话强烈建议看一下。
本文为学习笔记,文中的内容只是根据自己的工作需要和平时使用写了书中的部分内容,并且文中的示例代码大多直接贴的原文代码,当然,代码多数都在Python3.6的环境上都验证过了的。不同领域的编程关注点也会有所不同,有兴趣的可以去看全文。
python3-cookbook:https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html
10.2 控制模块被全部导入的内容
尽管强烈反对使用from xxx import *的形式来进行导入,但是当你真的需要用到这种形式时,需要注意以下几点:
- 这种形式不会导入以下划线开头的变量。
- 如果模块中(包括__init__.py)定义了__all__变量(列表类型),则只会导入__all__中定义的内容,即便__all__是一个空列表,而且列表中的模块名需要是字符串类型。
- 如果__all__中包含了未定义的名称,则会引起报错。
10.4 将模块分割成多个文件
当某个包中的模块太多,或者一个文件中的类、函数等太多之后,可以将它们在逻辑上统一成一个模块,以减小使用者的负担。
如有一个mymodule.py:
class A:
def spam(self):
print('A.spam') class B(A):
def bar(self):
print('B.bar')
新建一个包,将A和B分别定义在a.py和b.py两个文件:
mymodule/
__init__.py
a.py
b.py
# a.py
class A:
def spam(self):
print('A.spam')
# b.py
from .a import A
class B(A):
def bar(self):
print('B.bar')
# __init__.py
from .a import A
from .b import B
使用示例:
>>> import mymodule
>>> a = mymodule.A()
>>> a.spam()
A.spam
>>> b = mymodule.B()
>>> b.bar()
B.bar
>>>
以上__init__.py中的写法有一个缺点,就是会在导入时会一次性将全部模块都加载完成,可以考虑如下延迟加载的方案,但是也需要注意延迟加载这种方案在继承和类型检查时可能会被中断:
# __init__.py
def A():
from .a import A
return A() def B():
from .b import B
return B()
10.5 利用命名空间导入目录分散的代码
当你想给程序添加插件或者附加包时,可以考虑如下方案:
如有两个插件的代码目录结构如下,需要注意的是,这个目录结构中任何一层目录都是不能有__init__.py的:
foo-package/
spam/
blah.py bar-package/
spam/
grok.py
>>> import sys
>>> sys.path.extend(['foo-package', 'bar-package'])
>>> import spam.blah
>>> import spam.grok
>>>
>>> import spam
>>> spam.__path__
_NamespacePath(['foo-package/spam', 'bar-package/spam'])
>>>
10.7 运行目录或压缩文件
当使用Python去运行一个目录或者压缩文件时,如果目录或者压缩文件中含有__main__.py,则Python会将这个文件作为程序主文件来运行,通常,遇到这种情形,建议写一个简单的shell脚本来运行程序。
程序文件目录结构:
myapplication/
spam.py
bar.py
grok.py
__main__.py
运行程序目录:
bash % python3 myapplication
运行压缩文件:
bash % ls
spam.py bar.py grok.py __main__.py
bash % zip -r myapp.zip *.py
bash % python3 myapp.zip
... output from __main__.py ...
shell脚本:
#!/usr/bin/env python3 /usr/local/bin/myapp.zip
10.10 通过字符串名导入模块
当你想通过字符串来导入某个模块时,可以使用importlib.import_module()来进行导入,它返回的是生成的模块对象,你只需要将它保存在一个变量中,就可以像正常的模块一样使用它。
如果字符串中包含相对导入,需要给一个额外的参数,如__package__。
相对于使用内置的__import__()来达到同样的目的,import_module更加通用,所以推荐使用后者。
>>> import importlib
>>> math = importlib.import_module('math')
>>> math.sin(2)
0.9092974268256817
>>> mod = importlib.import_module('urllib.request')
>>> u = mod.urlopen('http://www.python.org')
>>>
import importlib
# Same as 'from . import b'
b = importlib.import_module('.b', __package__)
python3-cookbook笔记:第十章 模块与包的更多相关文章
- Python3学习笔记(urllib模块的使用)转http://www.cnblogs.com/Lands-ljk/p/5447127.html
Python3学习笔记(urllib模块的使用) 1.基本方法 urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, ...
- python学习笔记13(模块、包)
在Python中有一个概念叫做模块(module),比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块. 模块文件以.py后缀结 ...
- Python第十章-模块和包
模块和包 我们以前的代码都是写在一个文件中, 而且代码也比较短. 假设我们现在要写一个大的系统, 不可能把代码只写到一个文件中, 迫切想把代码写到不同的文件中, 并且能够在一个文件使用另一个文件中代码 ...
- 周末学习笔记——day03(模块,包)
一,复习 ''' 装饰器 @wraper # fn = wraper(fn) def fn(): pass def wrap(arg): def outer(func): # 可以用arg def i ...
- python学习笔记五:模块和包
一.模块用import导入 cal.py: #!/usr/bin/python def add(x,y): return x+y if __name__ == '__main__': print ad ...
- Python3学习笔记(urllib模块的使用)
转载地址:https://www.cnblogs.com/Lands-ljk/p/5447127.html 1.基本方法 urllib.request.urlopen(url, data=None, ...
- 【转】Python3学习笔记(urllib模块的使用)
原文地址:https://www.cnblogs.com/Lands-ljk/p/5447127.html 1.基本方法 urllib.request.urlopen(url, data=None, ...
- 笔记||Python3之模块与包
模块的概念:一个.py文件就称之为一个模块. 包的概念:把许多个模块按照功能放到不同的目录中来组织模块,这些组织存放模块文件的目录,我们称之为包. 模块与包的优势:1- 方便别人调用 2 - 避免同名 ...
- ansible笔记(9):常用模块之包管理模块
ansible笔记():常用模块之包管理模块 yum_repository模块 yum_repository模块可以帮助我们管理远程主机上的yum仓库. 此处我们介绍一些yum_repository模 ...
随机推荐
- [bzoj1045] [洛谷P2512] [HAOI2008] 糖果传递
Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数nn<=1'000'000,表示小朋友的个 ...
- 【Oracle】分区表详解
此文从以下几个方面来整理关于分区表的概念及操作: 1.表空间及分区表的概念 2.表分区的具体作用 3.表分区的优缺点 4.表分区的几种类型及操作方法 5.对表分区的维护 ...
- 绕过路由系统 (Bypassing the Routing System)| 高级路由特性
- 《ASP.NET Core 高性能系列》ASP.NET Core的启动过程(1)
一.一切从头开始 简述:知道事情的真相就应该从头 开始,下面我们代码先行 public class Program { public static void Main(string[] args) { ...
- Linux防火墙之iptables入门
一.防火墙的概念 什么是防火墙?防火墙是一台或一组设备,用以在网络间实施访问控制策略:事实上一个防火墙能够包含OSI模型中的很多层,并且可能会涉及进行数据包过滤的设备,它可以实施数据包检查和过滤,在更 ...
- java web 各个文件夹命名原因
今天突然被同学问然后就发现,自己有很多的疑问: (1) 为什么servlet的配置文件,命名为 web.xml , 内部是如何读取的,原因就是他内度的工作原理 (2) webINF Src 文件为什么 ...
- SpringBoot学习(三):日志
1.日志框架 小张:开发一个大型系统: 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? 2.框架来记录系统的一些运行时信息: ...
- BaseAdapter的三种表达式分析,startActivityForResult的使用
(一)BaseAdapter的三种表达式: ①逗比式: public View getView(int position, View convertView, ViewGroup parent) { ...
- 探究HashMap1.8的扩容
扩容前 扩容后 机制 else { // preserve order Node<K,V> loHead = null, loTail = null;//低指针 Node<K,V&g ...
- C++输出中文字符
注:本文转载自互联网,感谢作者整理! 1. cout 场景1: 在源文件中定义 const char* str = "中文" 在 VC++ 编译器上,由于Windows环境用 ...