Python 包管理

1. 模塊

  • 一個模塊就是一個包含python代碼的文件,后綴名稱是.py就可以,模塊就是個python文件

  • 為什么我們用模塊

    • 程序太大,編寫維護非常不方便,需要拆分
    • 模塊可以增加代碼重復利用的方法
    • 當作命名空間使用,避免命名沖突
  • 如何定義模塊

    • 模塊就是一個普通文件,所以任何代碼可以直接書寫
    • 不過根據(jù)模塊的規(guī)范,最好在本塊中編寫以下內(nèi)容
      • 函數(shù)(單一功能)
      • 類(相似功能的組合,或者類似業(yè)務(wù)模塊)
      • 測試代碼
  • 如何使用模塊

    • 模塊直接導入

      • 模塊名稱直接以數(shù)字開頭,需要借助importlib幫助
    • 語法

      import module_name
      module_name.function_name
      module_name.class_name

    • 案例 01.py,02.py,p01.py,p02.py

        # 案例 01.py
        # 包含一個學生類
        # 一個sayHello函數(shù)
        # 一個打印語句
    
        class Student():
            def __init__(self, name = "NoName", age = 18):
                self.name = name
                self.age = age
        
            def say(self):
                    print("My name is {0}".format(self.name))
        
        def sayHello():
            print("Hi, ")
        
        print("我是模塊p0")
        
    
        # 案例 02.py
        # 借助于importlib包可以實現(xiàn)導入以數(shù)字開頭的模塊名稱
        import importlib
        
        # 相當于導入了一個叫01的模塊并把導入模塊賦值給了a
        
        a = importlib.import_module("01")
        stu = a.Student()
        stu.say()
    
        # 案例 p01.py
        # 包含一個學生類
        # 一個sayHello函數(shù)
        # 一個打印語句
        
        class Student():
            def __init__(self, name = "NoName", age = 18):
                self.name = name
                self.age = age
        
            def say(self):
                    print("My name is {0}".format(self.name))
        
        def sayHello():
            print("Hi, ")
        
        # 此判斷語句建議一直作為程序的入口
        if __name__ == '__main__':
            print("我是模塊p01")
    
        # 案例 p02.py
        import p01
        
        stu = p01.Student("xiaojing", 19)
        
        stu.say()
        
        p01.sayHello()
    
          My name is xiaojing
          Hi, 
    
    • import 模塊 as 別名
      • 導入的同時給模塊起一個別名
      • 其余用法跟第一種相同
      • 案例 p03.py
        # 案例 p03.py
        import p01 as p
        
        stu = p.Student("yueyue", 18)
        stu.say()
    
          My name is yueyue
    
    • from module_name import func_name, class_name
      • 按上述方法有選擇性的導入
      • 使用的時候可以直接使用導入的內(nèi)容,不需要前綴
      • 案例 p04
        # 案例 p04.py
        from p01 import Student, sayHello
        
        stu = Student()
        
        stu.say()
        
        sayHello()
    
        My name is NoName
        Hi,    
    
    • from module_name import *
      • 導入模塊所有內(nèi)容
      • 案例 p05.py
        # 案例 p05.py
        from p01 import *
        
        sayHello()
        
        stu = Student("yaona", 20)
        stu.say()
    
          Hi, 
          My name is yaona
    
  • if __name__ == ``__main__ 的使用

    • 可以有效的避免模塊代碼被導入的時候被動執(zhí)行的問題
    • 建議所有程序的入口都以此代碼為入口

2. 模塊的搜索路徑和存儲

  • 什么是模塊的搜索路徑

    • 加載模塊的時候,系統(tǒng)會在哪些地方尋找此模塊
  • 系統(tǒng)默認的模塊搜索路徑

      import sys
      sys.path  屬性可以獲取路徑列表
      # 案例 p06.py
    
        # 案例 p06.py
        import sys
        
        print(type(sys.path))
        print(sys.path)
        
        for p in sys.path:
            print(p)
    
              <class 'list'>
          ['D:\\python\\project\\包管理', 'D:\\PyCharm Community Edition 2019.1.1\\helpers\\pydev', 'D:\\python\\project', 'D:\\PyCharm Community Edition 2019.1.1\\helpers\\third_party\\thriftpy', 'D:\\PyCharm Community Edition 2019.1.1\\helpers\\pydev', 'C:\\Users\\user\\.PyCharmCE2019.1\\system\\cythonExtensions', 'D:\\python\\project\\包管理', 'D:\\Anaconda3\\envs\\opp\\python37.zip', 'D:\\Anaconda3\\envs\\opp\\DLLs', 'D:\\Anaconda3\\envs\\opp\\lib', 'D:\\Anaconda3\\envs\\opp', 'D:\\Anaconda3\\envs\\opp\\lib\\site-packages']
          D:\python\project\包管理
          D:\PyCharm Community Edition 2019.1.1\helpers\pydev
          D:\python\project
          D:\PyCharm Community Edition 2019.1.1\helpers\third_party\thriftpy
          D:\PyCharm Community Edition 2019.1.1\helpers\pydev
          C:\Users\user\.PyCharmCE2019.1\system\cythonExtensions
          D:\python\project\包管理
          D:\Anaconda3\envs\opp\python37.zip
          D:\Anaconda3\envs\opp\DLLs  
          D:\Anaconda3\envs\opp\lib
          D:\Anaconda3\envs\opp
          D:\Anaconda3\envs\opp\lib\site-packages
    
  • 添加搜索路徑

      sys.path.append(dir)
    
  • 模塊的加載順序

    1. 搜索內(nèi)存中已經(jīng)加載好的模塊
    2. 搜索python的內(nèi)置模塊
    3. 搜索sys.path路徑

  • 包是一種組織管理代碼的方式,包里面存放的是模塊
  • 用于將模塊包含在一起的文件夾就是包
  • 自定義包的結(jié)構(gòu)
    |---包
    |---|---  __init__.py  包的標志文件
    |---|---  模塊1
    |---|---  模塊2
    |---|---  子包(子文件夾)
    |---|---|---  __init__.py
    |---|---|---  子包模塊1
    |---|---|---  子包模塊2
  • 包的導入操作

    • import package_name
      • 直接導入一個包,可以使用init.py中的內(nèi)容

      • 使用方式是:

          package_name.func_name
          package_name.class_name.func_name()
        
      • 此種方式的訪問內(nèi)容是

      • 案例 pkg01, p07.py

        # pkg01.__init__py
        def inInit():
            print("I am in init of package")
    
        # pkg01.p01.py
        class Student():
            def __init__(self, name = "NoName", age = 18):
                self.name = name
                self.age = age
        
            def say(self):
                    print("My name is {0}".format(self.name))
        
            def sayHello():
                print("Hi, ")
    
    
        print("我是模塊p01")
    
        # 案例 p07.py
        import pkg01
        
        pkg01.inInit()
    
          I am in init of package
    
    • import package_name as p

      • 具體用法跟作用方式,跟上述簡單導入一致
      • 注意的是此種方法是默認對init.py內(nèi)容的導入
    • import package.module

      • 導入包中某一個具體的模塊

      • 使用方法

          package.module.func_name
          package.module.class.fun()
          package.module.class.var
        
      • 案例 p08.py

        # 案例 p08.py
        import pkg01.p01
        
        stu = pkg01.p01.Student()
        stu.say()
    
          我是模塊p01
          My name is NoName
    
    • import package.module as pm
  • from ... import 導入

    • from package import module1, module2, module3, ... ...

    • 此種導入方法不執(zhí)行 __init__ 的內(nèi)容

        from pkg01 import p01
        p01.sayHello()
      
    • from package import *

      • 導入當前包 __init__.py 文件中所有的函數(shù)和類

      • 使用方法

          func_name()
          class_name.func_name()
          class_name.var
        
      • 案例 p09.py, 注意此種導入的具體內(nèi)容

        # 案例 p09.py
        from pkg01 import *
        
        inInit()
        
        stu = Student() 
    
          I am in init of package
          
          NameError: name 'Student' is not defined
    
  • from package.module import *

    • 導入包中指定的模塊的所有內(nèi)容

    • 使用方法

        func_name()
        class_name.func_name()
      
  • 在開發(fā)環(huán)境中經(jīng)常會引用其他模塊,可以在當前包中直接導入其他模塊中的內(nèi)容

    • import 完整的包或者模塊的路徑
  • __all__ 的用法

    • 在使用from package import * 的時候,* 可以導入的內(nèi)容
    • __init__.py 中如果文件為空,或者沒有 __all__, 那么只可以把 __init__ 中的內(nèi)容導入
    • __init__ 如果設(shè)置了 __all__ 的值,那么則按照 __all__ 指定的子包或者模塊進行加載
      如此則不會載入 __init__ 中的內(nèi)容
    • __all__=['module1', 'module2', 'package1'... ...]
    • 案例 pkg02,p10.py
        # pkg02.__init__.py
        __all__=['p01']
        
        def inInit():
            print("T am in init of package")
    
        # pkg02.p01.py
        class Student():
            def __init__(self, name = "NoName", age = 18):
                self.name = name
                self.age = age
    
            def say(self):
                print("My name is {0}".format(self.name))
        
            def sayHello():
                print("Hi, ")
        
        # 此判斷語句建議一直作為程序的入口
        if __name__ == '__main__':
            print("我是模塊p01")
    
        # 案例 p10.py
        from pkg02 import *
        
        stu = p01.Student()
        stu.say()
    
      My name is NoName
    

命名空間

  • 用于區(qū)分不同位置不同功能但相同名稱的函數(shù)或者變量的一個特定前綴

  • 作用是防止命名沖突

      setName()
      Student.setName()
      Dog.setName()
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容