127-豆豆学Python第三集

刘小泽写于19.6.22 函数是程序中可重用的那个部分,而模块就是一个可重用的程序

关于模块

模块(Modules)的目的就是在其他函数中重新使用一些函数,它可以被其他的程序导入然后运行

首先了解标准库模块

# 结果保存为test.py
import sys

print('The commands are:')
for i in sys.argv:
    print(i)

print('\n\nThe PATH is:',sys.path,'\n')

以上代码的意思是:

  • 通过import导入sys模块,这个模块就是包含了内置的一些python解释器和环境相关的功能,可以理解为系统功能(system)。运行这个命令,python就会寻找这个模块,内置模块会最先被找到

  • 另外注意到存在sys.argvsys.path,点号左边是模块名,右边是模块中的变量名,其实这样的写法和R很相似,可以避免同一个变量名在多个模块中同时存在时发生冲突

    • sys.argv 返回一系列命令行参数的列表,并且这个列表是以0为第一位索引的,例如,我们输入python test.py i am robot ,结果会返回4个元素:test.pyiamrobot ,可以看到它也会将程序名作为返回结果,并且作为第一个元素。注意:Python是从0开始计数的
    • sys.path返回的是一系列目录名称,相当于环境变量,如果模块不在当前返回的环境中,那么就需要将模块先放进去,然后才能加载
  • 和R一样,当前目录是指程序启动的目录。可以利用import os; print(os.getcwd()) 查看

  • 每次都写命令的全称(如sys.path)还是比较麻烦的,其实可以直接将模块导入(就像R中先将R包加载进来),利用from sys import argv 。虽然这种办法可行,但还是为了避免后续发生名称的冲突,依然推荐使用import方式

编写自己的模块

每一个脚本都是一个module,只需要将后缀名设为.py,例如定义一个hi函数,将他保存为myscp.py

def hi():
  print('Hi, mymodule.')
__version__='0.1'

下面使用这个新建的模块,重新新建一个脚本:

# 导入我们之前建立的python脚本前缀,代表着模块名
import myscp

myscp.hi()
print('Version', myscp.__version__)
# Hi, mymodule.
# Version 0.1

结果返回的就是myscp.py的模块hi__version__

__name__是什么意思?

看到上面的代码有一个__version__,它的意思是一个内置变量,统称为__name__。例如:新建一个文件new_module.py

print('hello')

def main():
  print('nihao')
if __name__ == '__main__':
  main()
  print('Imported from another module')

好,接下来两种运行方式,注意看区别:

# 第一种:直接运行
python new_module.py
# 结果:
hello
nihao
Imported from another module
# 第二种:导入模块
>>> import new_module
# 结果:
hello

可以看到,直接运行是可以全部输出的,但是导入的方式只输出最开始的一行内容。这是因为:每个python脚本(也就是python模块)都包含了内置的变量__name__,如果是直接运行的话,__name__相当于文件名(包括了后缀);如果是导入的话,__name__相当于导入的模块名(不包含后缀)

__main__就是直接运行时模块的名称(就是脚本全称)

可以利用这个特性来让模块用不同的方式运行,因此上面代码的意思可以理解为: 当模块直接运行时,def后的代码会直接运行;模块是导入的话,def后的代码不会运行

dir函数

它能够返回对象包含的属性名称,当dir() 有参数且参数是模块名称时,函数返回指定模块对应的名称列表;如果没有指定参数,则返回当前模块的名称列表

import sys
dir(sys)
dir()
# 这两种返回的名称是不相同的
# 如果这时新建一个变量a
a=5
dir()#结果会比之前多了一个a
# 将a再删除后
del a 
dir()#又会发生变化

关于包

python的程序是有层次结构的:变量常位于函数内部,函数和全局变量常位于模块内部,而包就是一个包含模块和一个特殊的__int__.py 文件的文件夹,这个文件夹目的就是向python表明:我是特殊的,其中包含了python的模块

例如:我们创建一个world的包,然后下面可以有asiaafrica的子包,然后这两个子包中分别存在chinasouth_africa 的模块,它的布局就会是这样:

- <某个在sys.path中的路径>
	- world/
  	- __init__.py
    - asia/
    	- __init__.py
      - china/
      	- __init__.py
        - test.py
     - africa/
    	- __init__.py
      - south_africa/
      	- __init__.py
        - foo.py

因此,包是一种能方便组织模块的管理方式

Yunze Liu
Yunze Liu
Bioinformatics Sharer

Co-founder of Bioinfoplanet(生信星球)

Next
Previous

Related