python里__all__ 属性分别在模块和包中的用法

一、在模块中的用法
在模块(*.py)中使用,其作用是导出__all__列表里的类、函数、变量等成员,
否则将导出modualA中所有不以下划线开头(注:下划线开头为私有,默认不导入)的成员,
在模块中使用__all__属性的好处,是可避免在相互引用时的命名冲突

示例: modualA.py
# 模块中定义 __all__
__all__ = ["fun1","class1"]
...
# end file modualA.py

使用:
from modualA import *

说明:
from modualA import * 导入模块modualA里的所有成员;
如果定义了__all__那么就导出列表中的所有,否则默认导出不以下划线开头的所有成员
本示例中,定义了__all__,因此只导入列表中的成员 ["fun1","class1"]

 

二、在包中的用法
在包的__init__.py中意为导出包里的模块,例如包pkgA,pkgA是一个文件夹

示例:pkgA/__init__.py
# 包中定义 __all__
__all__ = ["modualA","modualB"]
from modualA import class1, class2
from modualB import fun1, class3

....
# end file pkgA/__init__.py

使用:
from pkgA import *

以上语句即执行了pkgA下的__init__.py,
由于定义了__all__,因此导入列表中的两个模块["modualA","modualB"],以及这两模块下的函数和类

 

Python两个有趣属性

__all__可用于模块导入时限制

例如:

from module import *

此时被导入模块若定义了__all__属性,则只有all内指定的属性、方法、类可被导入

若没定义,则模块内的所有将被导入。

补充说明:

Python中,对于一个模块具有一个名为__all__的属性,该属性的值就是被 from ModuleName import *这样的语句绑定的属性列表;否则,这种类型的from语句将绑定模块中除了以下划线开始的属性(Python默认以下划线开始的属性为私有属性)外的所有属性。

这样的话,对于同一个名空间里面出现重名现象的概率就加大了,为了减少这种情况的发生,都会在模块开始处定义__all__属性的内容,写出可以被这种from类型导入的属性,可以参考shutil.py的写法。

下面的是os.py里面的一段代码:

__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", "defpath", "name", "path", "devnull"]

 

__slots__用于限定类属性

例如:

class A(object):

     __slots__ = ['var']

此时外部调用时,如:

a = A()
a.var = 4        
 # 不会报错
a.other = 4      # 此时则会抛出异常AttributeError