一、图片问题展示
情况一(本文遇到的问题):
运行结果
情况二(验证代码没问题):
运行结果
情况三(验证代码没问题):
运行结果
情况四(验证用):
运行结果
情况五(对比用):
为什么放五种情况,因为为了测试各种猜想,避免是因为其他原因导致的该问题。
二、问题说明
在一个类中导入一个第三方模块,类中定义的函数使用了这个模块,当我们在外部调用的时候,出现报错:该模块不存在。
三、问题原因
1. 涉及知识点:python作用域和命名空间;
2. 我们应该知道,类or函数中的普通变量or函数,相当于是局部变量(如果没有声明为全局变量的话),那么在类or函数外面是不能直接用的,例如类中的方法也需要进行调用使用。那么这里类中导入的第三方库,就相当在这个类的内部导入了这个第三方库的很多变量和函数,那么也是局部的,就在外面不能直接用。
四、解决方案
1. 在类外面,导入该模块。也就是在调用前导入;
2. 在这个函数里面导入这个模块。
3. 在这个函数中tool.module_name.function()。也就是访问该类的成员。
4. 在类中将该属性声明为全局属性
五、原理分析
一、python作用域与命名空间基本知识点:
1. python中函数,类和模块都会产生作用域;
2. 命名空间:
1、也称名字空间,是从名字到对象的映射。不同的命名空间在不同的时刻创建,有不同的生存期;
2、不同命名空间中的命名没有任何联系;
3、当调用函数时,就会为它创建一个局部命名空间;
4、类定义也是局部作用域中的另一个命名空间。
3.作用域:
1、作用域是Python的一块文本区域,这个区域中,命名空间可以被“直接访问”。这里的直接访问指的是试图在命名空间中找到名字的绝对引用(非限定引用);
2、举例说明:直接引用;直接使用名字访问的方式,如name,这种方式尝试在名字空间中搜索名字name。
间接引用;使用形如objname.attrname的方式,即属性引用,这种方式不会在命名空间中搜索名字attrname,而是搜索名字objname,再访问其属性。
二、结论
1. 类、函数、模块都会产生自己的命名空间,不同命名空间之间不能直接引用。
如果要用,那么需要间接引用,或者将某个属性(变量、函数、模块)声明为全局的命名空间。
至于作用域和命名空间更加深层次的研究和探讨,暂时不在本文范围内,如有需求,请参考六、参考引用。写得很详细。
六、参考引用
1. python中文文档: http://www.pythondoc.com/pythontutorial3/classes.html ;
2. Python进阶_关于命名空间与作用域(详解) https://www.jb51.net/article/114951.htm ;
3. 上面的写得特别好,深入了解学习,可以去研究研究。
七、其他说明
1. 学为己,不为人。本文主要用于自己学习,和记录。如有错误,请见谅,并且希望能指出,谢谢!