转载:http://python-china.org/t/725

参考:http://www.cnblogs.com/alamZ/p/6943869.html

用 __all__ 暴露接口,这是一种约定

 

Python 可以在模块级别暴露接口:

__all__ = ["foo", "bar"]

1、提供了哪些是公开接口的约定

  不像 Ruby 或者 Java,Python 没有语言原生的可见性控制,而是靠一套需要大家自觉遵守的”约定“下工作。比如下划线开头的应该对外部不可见。同样,__all__ 也是对于模块公开接口的一种约定,比起下划线,__all__ 提供了暴露接口用的”白名单“。一些不以下划线开头的变量(比如从其他地方 import 到当前模块的成员)可以同样被排除出去。

import os
import sys __all__ = ["process_xxx"] # 排除了 `os` 和 `sys` def process_xxx():
pass # omit

2、控制 from xxx import * 的行为

  代码中当然是不提倡用 from xxx import * 的写法的,但是在 console 调试的时候图个方便还是很常见的。如果一个模块 spam 没有定义 __all__,执行 from spam import * 的时候会将 spam非下划线开头的成员都导入当前命名空间中,这样当然就有可能弄脏当前命名空间。如果显式声明了 __all__import * 就只会导入 __all__ 列出的成员。如果 __all__ 定义有误,列出的成员不存在,还会明确地抛出异常,而不是默默忽略。

3、为 lint 工具提供辅助

  编写一个库的时候,经常会在 __init__.py 中暴露整个包的 API,而这些 API 的实现可能是在包中其他模块中定义的。如果我们仅仅这样写:

from foo.bar import Spam, Egg

  一些代码检查工具,如 pyflakes 就会报错,认为 SpamEggimport 了又没被使用的变量。当然一个可行的方法是把这个警告压掉:

  from foo.bar import Spam, Egg  # noqa

  但是更好的方法是显式定义 __all__,这样代码检查工具会理解这层意思,就不再报 unused variables 的警告:

from foo.bar import Spam, Egg

  __all__ = ["Spam", "Egg"]

  需要注意的是大部分情况下 __all__ 都是一个 list,而不是 tuple 或者其他序列类型。如果写了其他类型的 __all__,如无意外 pyflakes 等 lint 工具会无法识别出。

4、定义 all 需要注意的地方

  • 如上所述,__all__ 应该是 list 类型的
  • 不应该动态生成 __all__,比如使用列表解析式。__all__ 的作用就是定义公开接口,如果不以字面量的形式显式写出来,就失去意义了。
  • 即使有了 __all__ 也不应该在非临时代码中使用 from xxx import * 语法,或者用元编程手段模拟 Ruby 的自动 import。Python 不像 Ruby,没有 Module 这种成员,模块就是命名空间隔离的执行者。如果打破了这一层,而且引入诸多动态因素,生产环境跑的代码就充满了不确定性,调试也会非常困难。
  • 按照 PEP8 建议的风格,__all__ 应该写在所有 import 语句下面,和函数、常量等模块成员定义的上面。

  如果一个模块需要暴露的接口改动频繁,__all__ 可以这样定义: 

__all__ = [
"foo",
"bar",
"egg",
]

  最后多出来的逗号在 Python 中是允许的,也是符合 PEP8 风格的。这样修改一个接口的暴露就只修改一行,方便版本控制的时候看 diff

python里的“__all__ ”作用的更多相关文章

  1. python 模块中__all__作用

    test.py文件开头写上__all__=[func1,func2] 当其他文件导入  from test import * 只会导出"[func1,func2]"里面的,其他调用 ...

  2. Python中【__all__】的用法

    Python中[__all__]的用法 转:http://python-china.org/t/725 用 __all__ 暴露接口 Python 可以在模块级别暴露接口: __all__ = [&q ...

  3. 为什么在Python里推荐使用多进程而不是多线程

    转载  http://bbs.51cto.com/thread-1349105-1.html 最近在看Python的多线程,经常我们会听到老手说:"Python下多线程是鸡肋,推荐使用多进程 ...

  4. 为什么在Python里推荐使用多进程而不是多线程?

    最近在看Python的多线程,经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢?   要知其然,更要知其所以然.所以有了下面的深入研究: 首先强调背景: 1. ...

  5. Python里format()方法基本使用

    '''第一种:自然连接''' #format 连接字符串 str = '{}使用的python是{}版本'.format('我','3.6.5') print(str) #打印结果:我使用的pytho ...

  6. Python里的单下划线,双下划线,以及前后都带下划线的意义

    Python里的单下划线,双下划线,以及前后都带下划线的意义: 单下划线如:_name 意思是:不能通过from modules import * 导入,如需导入需要:from modules imp ...

  7. 为什么在Python里推荐使用多进程而不是多线程?(为什么python多线程无法增加CPU使用率?)

    最近在看Python的多线程,经常我们会听到老手说:“Python下多线程是鸡肋,推荐使用多进程!”,但是为什么这么说呢? 要知其然,更要知其所以然.所以有了下面的深入研究: 首先强调背景:     ...

  8. SNF快速开发平台3.0之--系统里广播的作用--迅速及时、简明扼要的把信息发送给接收者

    广播信息,即速度快捷.迅速及时.简明扼要的把信息发送给接收者. 当然在SNF快速开发平台上你也可以作为公告使用.不管当做什么使用要满足以下需求: 简单操作:页面操作简单 只需要输入内容就可以发送. 灵 ...

  9. Python里的类和对象简介

    ---恢复内容开始--- Python里的类  对象=属性+方法: 对象的属性主要是指主要的特征和参量,而方法主要是指函数: 类是一个具有一定特征和方法的集合,而对象是类的一个:类和对象的关系就如同模 ...

随机推荐

  1. easyui中tab页中js脚本无法加载的问题及解决方法

    我发现tab页中<script src="xxx.js">方式加载的脚本没有生效,firebug看请求也没有请求相应的脚本文件. 单独在浏览器中打开tab页中的页面js ...

  2. [poj] 1235 Farm Tour || 最小费用最大流

    原题 费用流板子题. 费用流与最大流的区别就是把bfs改为spfa,dfs时把按deep搜索改成按最短路搜索即可 #include<cstdio> #include<queue> ...

  3. hust 1605 bfs

    思路:直接用优先队列优化bfs. #include<map> #include<queue> #include<vector> #include<cmath& ...

  4. 图表绘制工具--Matplotlib 2

    ''' [课程3.] 基本图表绘制 plt.plot() 图表类别:线形图.柱状图.密度图,以横纵坐标两个维度为主 同时可延展出多种其他图表样式 plt.plot(kind='line', ax=No ...

  5. bzoj 1111 - 四进制的天平

    Description 给定 1000的十进制数, 求 最小的 四幂拆分 方案 有多少种 Solution 先大除法 \(n\log_4(n)\)次取余转化为 四进制数. 然后从 低位 往 高位 \( ...

  6. Java并发容器--ConcurrentHashMap

    引子 1.不安全:大家都知道HashMap不是线程安全的,在多线程环境下,对HashMap进行put操作会导致死循环.是因为多线程会导致Entry链表形成环形数据结构,这样Entry的next节点将永 ...

  7. 平衡二叉树DSW算法

    #include<iostream> #include<stdlib.h> #include<math.h> using namespace std; class ...

  8. linux硬盘分区表为gpt

    由于mbr最大支持2T不够用,给5T的新硬盘弄成GPT的 yum install -y parted#指定硬盘parted /dev/#p 查看分区#rm 1p 删除指定分区#改成gptmklabel ...

  9. Python学习杂记_12_函数(三)

    内置函数 Python有很多内置函数,以下这些是常用且必须要掌握的: 强制类型转换: bool() # 把一个对象转换成布尔类型 int() # 整形 float() # 小数 str() # 字符 ...

  10. 爬虫练习二:GUI+下载百思不得姐网站视频

    环境 python2.7 pycharm 课题:Python爬取视频(桌面版)---爬虫,桌面程序应用 优点:语法简洁,入门快,代码少,开发效率高,第三方库 1.图形用户界面---GUI 2.爬虫,爬 ...