zoukankan      html  css  js  c++  java
  • python包

    python包

           一个模块就是一个python文件,在python里为了对模块分类管理,就需要划分不同的文件夹。多个有联系的模块可以放在同一个文件夹下,为了称呼方便,一般把python里的一个代码文件夹称为一个包。

    一、包的定义

           现有以下包:newmsg,包里有三个模块,分别是__init__.py、sendmsg.py、recvmsg.py文件。在包的同级有个test.py文件,目标是在test.py文件里引入newmsg的两个模块sendmsg.py和recvmsg.py。

           

    需要强调的是:

    1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错

    2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是模块的一种形式

    二、包的使用

           sendmsg.py文件里的内容如下:

    def send_msg():
        print('——————sendmsg方法被调用了——————')
    

      recvmsg.py文件里的内容如下:

    def recv_msg():
        print('——————recvmsg方法被调用了——————')
    

      可以使用以下几种方法来导入模块,使用模块里的方法:

           1、直接使用包名.模块名导入指定的模块

    import newmsg.sendmsg
    newmsg.sendmsg.send_msg()

           2、使用from xxx improt xxx 方式导入指定模块

    from newsmsg import sendmsg,recvmsg
    sendmsg.send_msg()     #此时不需要写包名,直接写模块名
    recvmsg.recv_msg()

           3、使用__init__.py ,导入包里的指定模块。

              

              在__init__.py文件里编写代码:

    from . import sendmsg     #导入指定的模块     .代表的是当前文件夹
    

      test.py文件里的代码:

    import newmsg     #导入时,只需要输入包名即可。在包名的__init__.py文件里,导入了指定模块
    newmsg.sendmsg.send_msg()   #可以直接调用对应的方法
    newmsg.recvmsg.recv_msg()    #报错,不可以使用recvmsg模块,因为__init__.py文件没有导入这个模块
    

      包属于模块的一种,因而包以及包内的模块均是用来被导入使用的,而绝非被直接执行,首次导入包(如import newmsg)同样会做三件事:

           1、执行包下的__init__.py文件

           2、产生一个新的名称空间用于存放__init__.py执行过程中产生的名字

           3、在当前执行文件所在的名称空间中得到一个名字newmsg,该名字指向__init__.py的名称空间,例如newmsg.xxx和newmsg.yyy中的xxx和yyy都是来自于newmsg下的__init__.py,也就是说导入包时并不会导入包下所有的子模块与子包

           4、newmsg.sendmsg.send_msg() 要求newmsg下有名字sendmsg,进而newmsg.sendmsg下有名字send_msg。newmsg.sendmsg下已经有名字send_msg了,但newmsg下没有名字sendmsg,因此需要在包中的__init__.py文件中导入模块sendmsg(from . import sendmsg

           5、关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。

           6、包A和包B下有同名模块也不会冲突,如A.a与B.a来自两个命名空间。

           7、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件


            3.1绝对导入与相对导入

           针对包内的模块之间互相导入,导入的方式有两种:

           a、绝对导入:以顶级包为起始(因为包已经被使用者放入sys.path路径中)

    # newmsg下的__init__.py
    from newmsg import recvmsg
    

      b、相对导入:表示当前文件所在目录,.. 代表当前目录的上一级目录,以此类推

    # newmsg下的__init__.py
    from . import recvmsg

      同理,针对package1.package2.moudle.fuction(),则需要

    # 操作package1下的__init__.py,保证package1.package2
    from . import package2  或 from package1 import package2
    
    #操作package2下的__init__.py,保证package1.package2.moudle
    from . import moudle  或 from package1.package2 import moudle
    

      针对包内部模块之间的相互导入推荐使用相对导入,需要特别强调:

    • 相对导入只能在包内部使用,用相对导导入不同目录下的模块是非法的(包内模块之间的导入,推荐使用相对导入)
    • 无论是import还是from-import,但凡是在导入时带点的,点的左边必须是包,否则语法错误

    • 相对导入不能跨出包,所以相对导入仅限于包内模板彼此之间使用
    • 绝对导入是没有任何限制的,所以绝对导入是一种通用的导入方式

           3.2__init__.py其他用途

           __init__.py控制着包的导入行为。__init__.py为空仅仅是把这个包导入,不会导入包中的模块。可以在__init__.py文件中编写内容。
     
           __init__.py文件内容:
    print('hello,wold!')
    

           别的模块在引入这个包的时候,会自动调用这段代码:

    from newmsg import sendmsg,recvmsg
    sendmsg.send_msg()  

           运行结果:
               hello world!
               ——————sendmsg方法被调用了——————
     

           3.3__all__变量的使用

            在__init__.py文件中,定义一个__all__变量,它控制着from 包名 import * 时导入的模块。

            __init__.py文件:

    __all__=['sendmsg']
    

      test.py文件

    from newmsg import *
    sendmsg.send_msg()
    recvmsg.recv_msg()     #报错,recvmsg模块没被导入
    

         

  • 相关阅读:
    效果超酷的textarea的输入字数限提示
    【设计模式(七)】结构型模式之桥接模式
    【设计模式(六)】适配器模式
    【设计模式(四)】原型模式
    【设计模式(三)】工厂模式
    【设计模式(二)】单例模式
    【设计模式(一)】设计模式概览与六大设计原则
    【算法刷题】无重复字符的最长子串
    【算法刷题】全排列 II
    【算法刷题】LRU缓存模拟
  • 原文地址:https://www.cnblogs.com/shixiaoxun/p/14482783.html
Copyright © 2011-2022 走看看