1. 程式人生 > >模塊和包

模塊和包

版本號 賦值 名稱 應該 後者 錯誤 path 多版本 什麽是

一.模塊

  1.什麽是模塊

  一個模塊就是包含了python 定義和聲明的文件,文件名就是模塊名加.py後綴

  2.模塊的作用

  方便管理,使功能得到重復利用

  3.使用模塊

   3.1 模塊可以包含可執行的語句和函數的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導入import語句時才執行,第一次導入後就已將模塊名加載到內存中了。

   3.2 每個模塊都是一個獨立的名稱空間,定義在這個模塊中的函數,把這個模塊的名稱空間當作全局名稱空間,編寫自己的模塊時不用擔心與使用者的全局變量發生沖突。

   3.3 首次導入模塊my_moudle時會做三件事:

   

1.為源文件(my_moudle模塊)創建新的名稱空間,在my_moudle中定義的函數和方法若是使用到了global時訪問的就是這個名稱空間。

   2.在新創建的命名空間中執行模塊中包含的代碼,見初始導入import my_moudle

   3.創建名字my_moudle來引用該命名空間

   3.4 為模塊起名 

#import my_module as sm
#print(sm.money)

   3.5 在一行中導入多個模塊

#import sys,os,re

   3.6 from...import

#from my_module import read1,read2
#這樣可以
直接用模塊中的名字 #如果當前文件中有和module中一樣的名字比如都有read(),則會被覆蓋

  註意:python中的變量賦值不是一種存儲操作,而只是一種綁定關系

#from my_moudle import money,read1
#money=100 #將當前位置的名字money綁定到了100
#print(money) #打印當前的名字
#read1() #讀取my_moudle.py中的名字money,仍然為1000

‘‘‘
#from the my_moudle.py
#my_moudle->read1->money 1000
‘‘‘

   3.7 支持as,也支持多行導入

#
from my_moudle import read1 as read # from my_moudle import (read1, # read2, # money)

  3.8 from my_moudle import * 把my_moudle中所有的不是以下劃線(_)開頭的名字都導入到當前位置,大部分情況下我們的python程序不應該使用這種導入方式,因為*你不知道你導入什麽名字,很有可能會覆蓋掉你之前已經定義的名字。而且可讀性極其的差,在交互式環境中導入時沒有問題。

#from my_moudle import * #將模塊my_moudle中所有的名字都導入到當前名稱空間
#print(money)
#print(read1)
#print(read2)
#print(change)


#執行結果:
#from the my_moudle.py
#<function read1 at 0x1012e8158>
#<function read2 at 0x1012e81e0>
#<function change at 0x1012e8268>
#在my_moudle.py中新增一行

#__all__=[‘money‘,‘read1‘] 
#這樣在另外一個文件中用from my_moudle import *就這能導入列表中規定的兩個名字

  3.9考慮到性能的原因,每個模塊只被導入一次,放入字典sys.module中,如果你改變了模塊的內容,你必須重啟程序,python不支持重新加載或卸載之前導入的模塊

#def func1():
#    print(‘func1‘)

#import time,importlib
#import aa
 
#time.sleep(20)
   # importlib.reload(aa) #ctrl + s 可以更改
#aa.func1()

  4.0把模塊當作腳本執行

  我們可以通過模塊的全局變量__name__來查看模塊名:
  當做腳本運行:
  __name__ 等於‘__main__‘

  當做模塊導入:
  __name__= 模塊名

  作用:用來控制.py文件在不同的應用場景下執行不同的邏輯
  if __name__ == ‘__main__‘:

def fib(n):   
    a, b = 0, 1
    while b < n:
        print(b, end= )
        a, b = b, a+b
    print()

if __name__ == "__main__":
    print(__name__)
    num = input(num :)
    fib(int(num))

  4.1 模塊搜索路徑

   內存中已經加載的模塊->內置模塊->sys.path路徑中包含的模塊

  4.2 編譯python文件

  為了提高模塊的的加載速度,python解釋器會在__pycache__目錄中下緩存每個模塊編譯後的版本,格式為:module.version.pyc。通常會包含python的版本號。例如,在CPython3.3版本下,my_moudle.py模塊會被緩存成__pycache__/my_moudle.cpython-33.pyc。這種命名規範保證了編譯後的結果多版本共存。

二.包

   2.1

  1. 無論是import形式還是from...import形式,凡是在導入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包才有的導入語法

  2. 包是目錄級的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄)

  3. import導入文件時,產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字同樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件

  強調:

  1. 在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯,而在python2中,包下一定要有該文件,否則import 包報錯

  2. 創建包的目的不是為了運行,而是被導入使用,記住,包只是模塊的一種形式而已,包即模塊

  2.2

  註意:

1.關於包相關的導入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什麽位置,在導入時都必須遵循一個原則:凡是在導入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如item.subitem.subsubitem,但都必須遵循這個原則。

2.對於導入後,在使用時就沒有這種限制了,點的左邊可以是包,模塊,函數,類(它們都可以用點的方式調用自己的屬性)。

3.對比import item 和from item import name的應用場景:
如果我們想直接使用name那必須使用後者。

  2.3 from ..import ...

 需要註意的是from後import導入的模塊,必須是明確的一個不能帶點,否則會有語法錯誤,如:from a import b.c是錯誤語法

  2.4 __init__.py文件

  不管是哪種方式,只要是第一次導入包或者是包的任何其他部分,都會依次執行包下的__init__.py文件(我們可以在每個包的文件內都打印一行內容來驗證一下),這個文件可以為空,但是也可以存放一些初始化包的代碼。

模塊和包