【Python学习】python学习手册--第二十四章 高级模块话题

在模块中隐藏数据

在模块文件中,可以将变量名前加下划线(比如_X),可以防止在使用from * 语句导入该模块时,将那些下划线的变量名复制过去。这种方式并不是私有的声明,还是有其他方式获得这种下划线的变量名,比如import等等。
你还可以将变量名放在模块顶层的列表__all__中,以达到类似的相关,需要注意的是,用from * 执行变量导入时,只会复制__all__列表中的变量,这恰恰与下划线变量的作用相反。

模块属性__name__

每一个模块都有一个名为name的属性:

  • 如果该文件是以顶层文件执行,那么该模块的__name__属性就会设置成为“__main__”。
  • 如果该文件是以模块的方式导入其它文件,__name__就会改设成为客户端所了解的模块名。

实际上,属性”__name__”变量充当一个使用模式标志,它用来识别该程序是用作模块导入的还是用作顶层文件执行的。所以经常会看到 if __name__ == “__main__”的判断,当前模块如果用做顶层脚本执行时,就运行该if复合语句下的代码块,相反作为模块导入时,就不会执行。这种判断通常用於单元测试用

import 和from语句的as扩展

使用方法:

import modul as name

相当于

import modul
name = modul
del modul

from语句也可以使用:

from modul import name2 as name3
name3.func()                      #相当于直接调用name2中的函数func()

用字符串来指定导入模块

模块是对象,如果通过一个变量保存模块的名称,如何执行导入?

>>> import "string"          #无法直接通过字符串来导入模块
  File "<stdin>", line 1
    import "string"
                  ^
SyntaxError: invalid syntax
>>> x='string'                   
>>> import x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'x'
>>> 

为了解决这种问题,我们可以构建一个Python语句的字符串,通过动态构建这个字符串来指定要导入的模块,再通过exec函数来执行”Python代码”。

>>> x='string'   
>>> exec("import "+x)
>>> string
<module 'string' from '/usr/lib/python3.5/string.py'>
>>> 

exec的缺点是每次执行这个命令时都会去编译语句。如果使用一个内置的__import__语句来执行导入,代码运行速度应该会更快。

>>> nodename="string"   
>>> string=__import__(nodename)          #需要注意的是改内置函数会返回模块对象,需要将它保存于一个变量中。
>>> string
<module 'string' from '/usr/lib/python3.5/string.py'>
>>> 

模块设计理念

  • 总是在Python模块内部编写Python代码。
  • 模块的耦合性要降到最低:各个模块之间的变量尽量可能减少联系。模块应该封闭成为盒子,运行起来才会有最好的效果。
  • 最大化模块的粘合性:统一目标
  • 模块应该减少去修改其它模块的变量。

模块还有一些注意事项:

  • 模块顶层的代码都是按照顺序执行,这意味着顶层的代码无法引用文件后面才声明的变量。但是函数内部可以引用整个模块中赋值过的变量或其它函数
  • from语句是复制相同的变量名,相当于同变量名的拷贝。
  • reload不会影响from语句的导入,reload只是改变模块对象,而from是对模块内变量的拷贝,拷贝后并不会因模块本身改变而改变(import语句就不行了)
  • 当不同模块内有相同变量名时,必须使用import语句,这样使得调用变量时,加上必要的模块名称(命名空间)以区别使用的同名变量
  • 当使用递归导入(模块A需要导入模块B,而模块B又需要导入模块A)时,不要使用from语句,要使用import。在设计模块时,要避免这种导入的发生。这种导入很少见。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章