类中import第三方库,类中函数使用,类外引用该函数时,报错:该库找不到(python命名空间-作用域)

一、图片问题展示

情况一(本文遇到的问题):

运行结果

情况二(验证代码没问题):

运行结果

情况三(验证代码没问题):

运行结果

情况四(验证用):

运行结果

情况五(对比用):

为什么放五种情况,因为为了测试各种猜想,避免是因为其他原因导致的该问题。

二、问题说明

在一个类中导入一个第三方模块,类中定义的函数使用了这个模块,当我们在外部调用的时候,出现报错:该模块不存在。

三、问题原因

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. 学为己,不为人。本文主要用于自己学习,和记录。如有错误,请见谅,并且希望能指出,谢谢!

猜你喜欢

转载自blog.csdn.net/qq_41914687/article/details/113407772
今日推荐