20 Python __all__

本文详细介绍了Python中__all__的作用及其用法。当使用from module import *时,__all__用于控制导入哪些成员。文章通过示例展示了__all__在不同情况下的行为,并解释了其对模块导入的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python __all__

转载请标明出处(http://blog.youkuaiyun.com/lis_12/article/details/53574885).

__all__的作用

使用from module import * 导入模块时,

  1. 没有定义__all__

    将导入模块中所有不以下划线(‘_’)开头的成员。

  2. 定义了__all__

    1) 除了__init__.py以外的文件中定义__all__

    ​ 将导入__all__列表里的类、函数、变量等成员;

    2) 在__init__.py中定义了__all__

    ​ 将导入__all__列表里的类、函数、变量、模块等成员;

    ​ 搜索顺序:首先搜索类、函数、变量,如果未找到,则在当前路径下搜索文件;

    导入模块时,如果未找到__all__中的成员,抛出AttributeError。

注意:

  1. __all__ 只影响from module import * 这种导入方式,对from module import something 没有影响;
  2. 一个文件中定义了多个__all__时,以 后编译的__all__为准;

测试code

两个python文件

  1. A_no_all.py

    
    #!/usr/bin/python
    
    
    # -*- coding: utf-8 -*-
    
    a_no_all = 1
    _a_no_all = 2
    b_no_all = 3
    _b_no_all = 4
    class Foo_no_all(object):
       a = 0
    
    def fun_no_all():
       pass
  2. A_have_all.py

    '''验证是__all__是否与变量位置有关,结果证明无关...'''
    a_have_all = 1
    _a_have_all = 2
    
    __all__ = ['Foo_have_all','_a_have_all']   #如果里面的变量名不存在,别的文件导入时才会报错
    
    b_have_all = 3
    _b_have_all = 4
    class Foo_have_all(object):
       a = 0
    
    def fun_have_all():
       pass

除了__init__.py以外的文件中定义__all__

  1. 导入没有定义__all__的模块

    from A_no_all import *
    
    no_all = ['a_no_all','_a_no_all','b_no_all','_b_no_all','Foo_no_all','fun_no_all']
    
    for i in no_all:
       print '%-12s import?'%i,i in vars()
    
    d = globals()
    for i in no_all:
       if i in d:
           print '%s = %s'%(i,d[i])
    '''以下划线开头的变量没有导入...
    a_no_all     import? True
    _a_no_all    import? False
    b_no_all     import? True
    _b_no_all    import? False
    Foo_no_all   import? True
    fun_no_all   import? True
    a_no_all = 1
    b_no_all = 3
    Foo_no_all = <class 'A_no_all.Foo_no_all'>
    fun_no_all = <function fun_no_all at 0x000000000332C198>
    '''
  2. 导入定义了__all__的模块

    from A_have_all import *
    have_all = ['a_have_all','_a_have_all','b_have_all','_b_have_all','Foo_have_all','fun_have_all']
    
    for i in have_all:
       print '%-12s import?'%i,i in vars()
    
    d = globals()
    for i in have_all:
       if i in d:
           print '%s = %s'%(i,d[i])
    '''仅导入了__all__中的成员,不管变量名是否以“_”开头
    a_have_all   import? False
    _a_have_all  import? True
    b_have_all   import? False
    _b_have_all  import? False
    Foo_have_all import? True
    fun_have_all import? False
    _a_have_all = 2
    Foo_have_all = <class 'A_have_all.Foo_have_all'>
    '''

__init__.py中定义__all__

文件位置

这里写图片描述

  1. __init__.py为空

    test.py代码如下

    from packet import *  #执行packet目录下的__init__.py
    for i in  globals().keys():
       print i
    '''
    __builtins__
    __file__
    __package__
    __name__
    __doc__
    '''

    从代码可知,未将A_no_all.py和A_have_all.py导入。

  2. __init__.py内容如下

    from A_have_all import *
    from A_no_all import *

    test.py内容如下

    from packet import *
    for i in globals.keys():
       print i
    '''
    Foo_have_all
    A_have_all,A_have_all中的成员,仅导入了A_have_all中__all__中的成员
    
    Foo_no_all
    fun_no_all
    a_no_all
    b_no_all
    A_no_all,A_no_all中的成员,导入了不以_开头的成员
    ...
    '''
  3. __init__.py内容如下

    __all__ = ['A_have_all','A_no_all']

    test.py内容如下

    from packet import *  #此时与from packet import A_no_all,A_have_all等价
    for i in globals().keys():
       print i
    '''
    A_no_all
    A_have_all
    ...
    '''
    print A_no_all.__dict__
    print A_have_all.__dict__

    如果在__init__.py中定义了__all__,首先搜索变量、函数、类,如果未找到,则在当前路径下搜索文件。

    foo.py内容如下,foo.py与A_have_all.py在同一路径下

    __all__ = ['A_have_all']

    在别的文件导入foo

    from foo import *   #AttributeError: 'module' object has no attribute 'A_have_all'

    以上代码可以证明,只有在__init__.py定义了__all__时才会搜索文件…

  4. __init__.py内容如下

    from A_have_all import *
    from A_no_all import *
    __all__ = ['a_no_all','_a_have_all']#包含的是变量名

    test.py内容如下

    from packet import *
    for i in globals().keys():
       print i
    '''
    _a_have_all
    a_no_all,仅导入了__init__.py中__all__中的两个成员变量
    ...
    '''
  5. 修改A_have_all,让变量名与文件名一致,内容如下

    A_have_all = 1

    __init__.py内容如下

    from A_have_all import *
    __all__ = ['A_have_all']#与文件名字相同的变量名

    test.py代码如下

    from packet import *
    print A_have_all        #导入的是变量,不是文件名,变量,函数,类的优先级>模块
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值