• 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都是内置模块)
    • 开源模块(一些大牛写的比较好的模块)
  • 相关阅读:
    gridView 表头自适应高度
    Devexpress GridView 数据格式化显示
    CSharpCodeProvider 生成代码
    浅谈C#中Control的Invoke与BeginInvoke在主副线程中的执行顺序和区别
    关于appdomain, assembly, 进程,线程的概念体会
    所有子线程全部结束的判断
    主线程如何捕获子线程异常
    时间戳与展示时间互相转化
    跨域 jsonp 和 CORS 资料
    之前的前端同事聊天关于百姓网
  • 原文地址:https://www.cnblogs.com/win0211/p/8421782.html
Copyright © 2020-2023  润新知