python里的“__all__ ”作用

转载: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

时间: 2024-11-25 07:29:03

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

在python里如何动态添加类的动态属性呢?

body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5;

python里的splitlines详解

Python的split方法函数可以分割字符串成列表,默认是以空格作为分隔符sep来分割字符串. In [1]: s = "www jeapedu com" In [2]: print s.split() ['www', 'jeapedu', 'com'] 当然可以改变sep分割字符串为其他字符串. In [6]: t = "www.jeapedu.com" In [7]: print t.split(".") ['www', 'jeapedu'

python里多线程的写法

python里多线程的写法 今天用到python多线程的时候, 发现不知道如何正确的等待所有线程结束后再结束主线程. 其实到最后我才知道这都是杞人忧天, Thread()出来的实例本来就是等到主进程结束后才结束. 官方解释: daemon A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called

python里的拆包、引用、递归与匿名函数

拆包:*A拆元组,**B拆字典. 引用:在C.C++里面里面a=1,b=a,实际上相当于硬链接,相当于两份a.b各有一个1,多占一个空间,而在python里就是软连接,只有一份,通过id(a)来查看id都一样, 在python里定义的东西如一直没引用,那么就会成为垃圾,不用担心,python有自己的机制去除垃圾. 不可变类型:数字.字符串.元组. 可变类型:列表.字典,它们都不能做字典的key. 递归:一个函数里调用了这个函数自己,递归完成阶乘,3的阶乘=3*(2的阶乘) 递归时一定要想到何时要

python里三种等待元素的方法

在做web或app的自动化测试经过会出现找不到元素而报错的情况,很多时候是因为元素 还没有被加载出来,查找的代码就已经被执行了,自然就找不到元素了.那么我可以用等待 元素加载完成后再执行查找元素的code. Python里有三种等待的方式:一. 强制等待 Sleep(54) 这个方法在time模块,使用时通过from time import sleep导入比如: Sleep(10) #表示强行等待10s再执行下一句代码 Driver.find_element_by_xpath("xxxxxx&q

<转载> 为什么在Python里推荐使用多进程而不是多线程?

最近在看Python的多线程,经常我们会听到老手说:"Python下多线程是鸡肋,推荐使用多进程!",但是为什么这么说呢?                要知其然,更要知其所以然.所以有了下面的深入研究: 首先强调背景:        1.GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定.        2.每个CPU在同一时间只能执行一个线程(在单核CPU下的多线程其实都只是并发,不是

二进制转换、字符编码的演化、Python里使用的编码、浮点数、浮点数的精确度问题

二进制转换 二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二",由18世纪德国数理哲学大师莱布尼兹发现.当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的.计算机中的二进制则是一个非常微小的开关,用"开"来表示1,"关"来表示0. 古时候敌人来了,如何通信呢? ①派人跑着去通知,速度太慢,等人回来,仗也打完了.

python里字典的用法介绍

一.什么是字典 字典是python里的一种数据类型,特点是元素的无序性,和键key的唯一性.字典的创建方法是{key:values},字典里的键key只能是不可变的数据类型(整型,字符串或者是元组),值values可以是任何数据类型.字典里的一组key:values叫做一个键值对item. 二.字典的基本操作 首先我们创建一个字典: a={'name':'tom','age':18,'sex':'male','height':'175cm'} b={'one':111,'name':'lisa'

python里的if __name__ == '__main__'是啥意思,简单点

简单来说,if __name__ == '__main__'表示: 当python文件直接被运行时,if __name__ == '__main__': 语句下面的代码段将被执行.当python文件以模块形式被调用时,if __name__ == '__main__': 语句下面的代码段不会被执行. 就两句话的事,网上花里胡哨的说了一堆无关紧要的话. python里的if __name__ == '__main__'是啥意思,简单点 原文地址:https://www.cnblogs.com/iM