__all__ 是干嘛用的?

前言

前两天写代码的时候在一个简单的导入操作上竟然卡了有半小时之多,弄了半天才发现问题所在,分享给大家,希望对大家有所借鉴。

from 模块 import *

我们导入模块通常用 from 模块名 import * , 之前我一直认为,就是导入这个模块内的所有属性和方法,但事实并非如此,python 通过 __all__内置变量来决定 哪些属性和方法可供外部使用,我们具体来看例子:

我们首先创建个 了 text1.py 文件 ,内容如下:

# 测试变量
param1 = "param1"
param2 = "param2"
# 测试函数
def test1():
    print("method test1() has been used")
def test2():
    print("method test2() has been used")
# 测试类, 这里重新定义了魔法方法__call__,使得对象实例也可以像方法一样被调用
class Test1():
    def __call__(self):
        print("class Test1() has been used!")
class Test2():
    def __call__(self):
        print("class Test2() has been used!")
__all__ = ['param1', 'test1', 'Test1']
if __name__ == "__main__":
    # 当前程序文件使用相关变量、方法、类
    print(param1, param2)
    test1()
    test2()
    T1 = Test1()
    T1()
    T2 = Test2()
    T2()

我们可以看到 ,在test1.py模块文件内部,我们可以顺利的调用所有的测试变量,测试类,测试方法,另外,我们在模块文件内部定义了 __all__ = ['param1', 'test1', 'Test1'],这个有什么用呢,我们暂时看不出.

我们再新建个test2.py文件,内容如下:

from test1 import *
try:
    print(param1)
except NameError as err:
    print(err, ", no variable param1")
try:
    print(param2)
except NameError as err:
    print( "no variable param2")
try:
    test1()
except NameError as err:
    print(err, ", no method test1()")
try:
    test2()
except NameError as err:
    print("no method test2()")
try:
    T1 = Test1()
    T1()
except NameError as err:
    print(err, ", no calss Test1()")
try:
    T2 = Test2()
    T2()
except NameError as err:
    print("no class T2()")

执行结果如下:

param1
no variable param2
method test1() has been used
no method test2()
class Test1() has been used!
no class T2()

从执行结果可以看出,虽然我们在test2.py文件开头就用from test1 import * 导入了test1 模块中的所有变量和 函数方法,但从结果似乎不是如此,param2,test2(),和Test2都找不到,也就是没导入进来,而这几个变量或者方法恰恰是 在 test1.py 模块文件中的 __name__ 变量没有定义的, 所以,并不是 from 模块名 import *就导入 该模块的所有内容,而是一次导入模块中通过__all__变量指定的所有对象。所以,我们可以通过__all__变量 来决定哪些内容是否要提供给外部调用。

思考题 ,模块中 定义的私有变量(单下划线或双下划线) 是否也受 all 变量控制?

本文分享自微信公众号 - 软件测试架构师俱乐部(gh_03227f9a322f),作者:鲲鹏

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 性能测试案例:redis获取不到连接池,Timeout waiting for idle object

    这是几个月前压测某项目登录接口时遇到的性能问题,虽然大家不一定会遇到,但是分析定位问题的思路还是可以参考一下。

    cctester
  • python 魔法方法连载四 __new__()

    在学习__new__(cls,[ *args]) 方法之前,我们知道,当实例化一个对象时,首先调用的是 __init__()方法初始化对象,但在我们学习了了__...

    cctester
  • 从0到1开发测试平台(八)后端服务添加lombok第三方类库

    Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。

    cctester
  • 对!非肿瘤发生信文章就是这么简单!

    Potentially critical roles of TNPO1,RAP1B,ZDHHC17,and PPM1B in the progression o...

    科研菌
  • SpringBoot注解大全,收藏一波!!!

    @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration...

    芋道源码
  • SpringBoot 注解大全,收藏一波!!!

    @SpringBootApplication:包含了@ComponentScan、@Configuration和@EnableAutoConfiguration...

    全栈自学社区
  • Spring Boot 最最最常用的注解梳理

    @SpringBootApplication: 包含了@ComponentScan、@Configuration和@EnableAutoConfiguratio...

    芋道源码
  • 让老电影“重生”的AI超分辨技术,即将形成一波热点

    最近有件大事,11 月 15 日,全球瞩目的经典电影《海上钢琴师》4K 修复版即将登陆全国院线。岁月侵蚀的影片经典场景,在老胶片的保存下只剩模糊的影像。而此次经...

    AI科技评论
  • Google 最美女工程师眼中的机器学习

    关于 Machine learning 机器学习,各位老司机应该不陌生。在众多关于机器学习概念的解释中,Google 首席决策情报工程师 Cassie Kozy...

    HyperAI超神经
  • Vue 项目报错:‘$‘ is not defined ( no-undef )

    报错如上图所示,错误原因是不认识 $ 符,他是 JQuery 中得符号,我也确实引入了 JQuery:

    wsuo

扫码关注云+社区

领取腾讯云代金券