10、Python之模块

    模块

    1、模块的定义:用来从逻辑上组织python代码来实现一个特定的功能,本质上就是以.py结尾的python文件。

    2、模块的导入方法

         假设有2个模块module_01和module_02,其代码如下:

1 #module_01模块
2 module_name = "module_01"
3 def sayHi(call_name):
4     print("在module_01中执行,被%s调用" % call_name)
5 def logger():
6     print("logger in the %s" % module_name)
1 #module_02模块
2 module_name = "module_02"
3 def sayHi(call_name):
4     print("在module_02中执行,被%s调用" % call_name)
5 def logger():
6     print("logger in the %s " % module_name)

1、import module_name   (导入单个模块module_name)

1 #main 模块
2 import module_01 #导入module_01模块
3 module_name = "main"
4 module_01.sayHi("main") #执行结果在module_01中执行,被main调用

 

 2、import module_name,module2_name(导入多个模块module_name,module2_name)

#main 模块
import module_01,module_02 #导入module_01,module_02模块
module_name = "main"
module_01.sayHi("main") #执行结果在module_01中执行,被main调用
module_02.sayHi("main") #在module_02中执行,被main调用

 3、from module_name import *(导入module_name模块中的所有代码,慎重

1 #main 模块
2 from module_01 import *
3 module_name = "main"
4 sayHi(module_name) #执行结果 在module_01中执行,被main调用
5 logger() #执行结果 logger in the module_01

    注意,这种导入方式本质上是将module_01的所有代码复制一份,放在main模块中,所以在调用module_01模块中的变量和函数时,不需要加模块名。那为什么要慎用呢,让我们对main模块中的代码进行修改一下。

#main 模块
from module_01 import *
module_name = "main"
def logger():
    print("logger in the %s" % module_name)
logger()

此时调用logger函数时,执行的结果应该是logger in the main。也就是说执行了mian模块中的looger函数而不是module_01。根据上面说的from module_01 import *这种导入方式就是将模块中的所有代码放到mian模块中,因此上面main模块的代码又等价于

 1 #main 模块
 2 #from module_01 import *
 3 #--------------module_01模块的代码------------------
 4 module_name = "module_01"
 5 def sayHi(call_name):
 6     print("在module_01中执行,被%s调用" % call_name)
 7 #----------------mian模块的代码--------------------
 8 def logger():
 9     print("logger in the %s" % module_name)
10 module_name = "main"
11 def logger():
12     print("logger in the %s" % module_name)
13 logger()

对于变量module_name来说,代码的第4行赋值值为"module_01",然后在代码的第10行又赋值为"main",所以module_name的值就是"main",由于函数名及变量名,所以logger函数也是同样的道理。那么问题来了,如果此时main函数的代码是这个样子的:

#main 模块
module_name = "main"
def logger():
    print("logger in the %s" % module_name)
from module_01 import *
logger()

执行的结果会是神马样子呢?

4、from module_name import m1,m2(导入模块module_name中m1,m2)

     此类导入省去,太简单我都不好意思说了

5、from module_name import m1 as m1_test (导入模块module_name中m1并修改m1的名字为m1_test)

     之前第3种导入方式存在的一个问题是,如果main模块中也定义了looger函数,这时候就会和module_01模块中的looger相互覆盖,第5种导入方式就是为了解决这个问题:

1 #main 模块
2 module_name = "main"
3 from module_01 import logger as module_01_logger
4 def logger():
5     print("logger in the %s" % module_name)
6 logger() #执行结果 logger in the main
7 module_01_logger() #执行结果 logger in the module_01

6、import package_name(导入包)

python中包的含义本质上就是带有__init__.py文件的目录,而导入包之后,只能调用该包的__init__.py文件中的函数和变量。例如:

1 #package_01中的__init__.py
2 def logger():
3     print("logger in the package_01__init__.py")

main模块中的代码如下:

#main 模块
import package_01
package_01.logger() #执行结果 logger in the package_01__init__.py

这时,我们在package_01增加一个模块package_module_01,代码如下:

1 #package_01包下面的package_module_01.py
2 def logger():
3     print("logger in the package_module_01.py")

这时候,我想在模块中调用package_module_01中的logger方法,main模块的代码如下:

#main 模块
import package_01
package_01.package_module_01.logger() #执行结果 报错:AttributeError: module 'package_01' has no attribute 'package_module_01'

纳尼?报错了,悲剧了!正如我们之前说的,对于包的导入而言,我们只能调用__init__.py中的变量和函数,我们如果需要调用package_module_01中的变量和函数时,就需要借助__init__.py来做一个桥梁,我们先在__init__.py中导入package_module_01。使用语句:from .import package_module_01,这时候我们再执行main模块就成功了。

7、动态导入模块

    有时候,我们需要动态导入模块,这时就需要使用标准模块importlib来实现。具体代码如下:

1 import importlib
2 aa = importlib.import_module("lib.aa")
3 print(aa.name)

其中“lib.aa”是指lib包下aa模块,在aa模块下有一个name变量,通过行2的代码就可以动态导入模块,然后对其模块中的数据和方法进行访问。

3、路径搜索

    上面我们说的模块和包的导入都是基于各个模块在同一个目录上,那么,如何处理不同目录之间模块的导入呢?其实我们说,模块的导入是分2步完成的,路径搜索和模块处理,下面我们看如何导入其它目录的模块。

     假设有2个目录dir_01和dir_02,其中dir_01中有一个模块module_01,module_01中有一个logger函数,dir_02中有一个模块module_02,我们的需求是在module_02中导入module_01调用其logger函数。

#dir_01目录下的module_01模块
def logger():
    print("logger in the module_01")
1 #dir_02目录下的module_02模块
2 import sys,os
3 DIR_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
4 sys.path.append(DIR_PATH)
5 from dir_01 import module_01
6 module_01.logger() #执行结果 logger in the module_01

其中sys,os都是系统标准的模块,__file__获取当前文件的相对路径,os.path.abspath()获取文件的绝对路径,os.path.dirname()获取当前目录的上级目录,sys.path.append()将路径添加到系统的环境变量中。这时候我们再使用模块导入语句:from dir_01 import module_01就可以找到module_01模块了。

4、模块分类:

模块分为三种:

  • 自定义模块(咱们上面写的全是自定义模块)
  • 内置标准模块(又称标准库 os,sys都是内置模块)
  • 开源模块(一些大牛写的比较好的模块)
posted @ 2018-02-06 12:51  高文祥888888  阅读(200)  评论(0编辑  收藏  举报