python -- 模塊與包

1、模塊
 
模塊就是一個包含了python定義和申明的文件,文件名就是模塊的名字加上.py的後綴/
模塊的分類:
    一、使用python編寫的py文件
    二、已被編譯位共享庫或者DLL或C或者C++的擴展
    三、包好一組模塊的包
    四、使用c編寫並鏈接到python解釋器的內置模塊
 
使用模塊是爲了讓咱們寫的代碼能夠重用,不至於把全部的文件都寫到一個py文件內。若是都寫在一個py文件內,項目大時,不易維護。
 
導入模塊的兩種方式
一、import模塊
二、from XXX import XXXX
 
yitian.py
print('...................')

main_actor = '張無忌'
main_actress = '趙敏'
fan_main_actor = '成昆'
fan_main_actress = '周芷若'

def light_war():
    print(f"{main_actor}破壞了{fan_main_actor}的陰謀詭計")

def shaolin_war():
    print(f"{main_actor}戰勝了{fan_main_actress}")

def ending():
    print(f"{main_actor}和{fan_main_actress}幸福的在一塊兒了")

def change(name):
    global main_actor
    main_actor = name
print("..................."
金庸來也
jinyong.py
 
import sys
import yitian as yt  # as 給模塊從新命名# pycharm報錯,模塊路徑有差別
# sys.path  搜索模塊的路徑
# print(sys.path)
# import yitian  # 若是已經到若是該模塊,此時則不會再執行模塊中的代碼了

print(yt.main_actor)
# print(main_actor)   報錯  當前名稱空間中沒有main_actor

yt.light_war()
yt.shaolin_war()
yt.ending()
導入模塊後的流程:
 
一、在導入模塊的開始,python解釋器會先經過sys.modules 來判斷愛模塊是否已經導入了該模塊,若是導入了,則不會再導入。若是該模塊還未導入過,則系統會作三件事:
        一、爲導入的模塊創立新的名稱空間
        二、在新建立的名稱空間中運行該模塊中的代碼
        三、建立模塊的名字,並使用該名稱做爲該模塊在當前模塊中引用的名字(前提時沒有as)
 
可使用globals來查看模塊的名稱空間
 
print(globals())

結果:

{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000172F298C1D0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:/python_workspace_hxt/day24 內置模塊 re/yitian.py', '__cached__': None, 'main_actor': '張無忌', 'main_actress': '趙敏', 'fan_main_actor': '成昆', 'fan_main_actress': '周芷若', 'light_war': <function light_war at 0x00000172F2881E18>, 'shaolin_war': <function shaolin_war at 0x00000172F2BFA268>, 'ending': <function ending at 0x00000172F2BFA158>, 'change': <function change at 0x00000172F9C3A400>}

 

 

注: 因爲模塊在導入的時候會建立本身的名稱空間,因此在使用模塊中的變量的時候通常不會產生衝突 python

 
import yitian as yt

main_actor = '周遊'
print(yt.main_actor)  # 張無忌
print(main_actor)   # 周遊
特別注意:若是咱們在不統的模塊這種引入了同一個模塊,而且在某一個模塊中改變了被引入模塊中的全局變量,則其餘模塊看到的之也跟着變,緣由是python的模塊只會引入一次,你們共享一個名稱空間
 
在yitian.py中添加以下代碼
def change():
    global  fan_main_actress
    fan_main_actress = '張美欣'

jingyong1.pyjson

import yitian  as  yt
yt.fan_main_actress = '周星娜'

jingyong.pydom

import  yitian as  yt
import  jingyong1

print(yt.fan_main_actress)  # 周星娜
出現上述問題的緣由
 
    一、你們同享一個模塊的名稱空間
     二、在jinyong1.py中改變了反角的名字
 
解決方案:
利用__name__這個內置變量,在python中,每一個模塊都有本身的__name__可是這個__name__的值是不定的。當咱們把一個模塊做爲程序運行的人口時,此時該模塊的__name__是「__main__」而若是咱們把模塊導入時,此時模塊內部的__name__就是該模塊自身的名字
 
在jinyong1.py
print(__name__)

# 結果爲__main__

  在jinyong.py中ui

import jinyong1

print(__name__)

結果爲 jinyong1
     
  咱們能夠利用這個特性來控制模塊內哪些代碼是在被加載的時候就運行的,哪些時在模塊被別人導入的時候就要執行的,也能夠屏蔽掉一些不但願別人導入就運行的代碼
 
if __name__=='__main__':
    yitian.main_actor = '張無忌'  # 此時,只有從該模塊做爲入口運行的時候纔會把main_actor設置爲張無忌
    print('張無忌實際上是一個渣男')  # 只有運行該模塊纔會打印,import的時候是不會執行這裏的代碼的
 
咱們還能夠對導入的模塊進行重命名
import yitian as yt  # 導入yitian,可是名字被重命名爲yt,就比如變量賦值同樣
a = 1 b = a

yt.shaoli_war()  # 此時能夠正常運行

print(globals())


{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002CC30D7C1D0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:/python_workspace_hxt/day24 內置模塊 re/practice24.py', '__cached__': None, 're': <module 're' from 'C:\\Users\\huxia\\AppData\\Local\\Programs\\Python\\Python36\\lib\\re.py'>, 'sys': <module 'sys' (built-in)>, 'yt': <module 'yitian' from 'F:\\python_workspace_hxt\\day24 內置模塊 re\\yitian.py'>}

一次也能夠導入多個模塊spa

import time,random,json,yitian
正確的導入模塊順序:
 
    一、全部的模塊導入都要寫在最上面,基本
     二、先引入內置模塊
     三、再引入擴展模塊
     四、最後引入本身定義的模塊
 
 
3、from  XXX  import  XXX
     在使用from的時候,python也會給咱們的模塊建立名稱空間,這一點和import是同樣的,可是from XXX import XXXX
的時候,只是把這個空間中的一些變量引入過來,部分導入。當一個模塊中的內容過多的時候,能夠選擇性的導入要使用的內容。
  from的坑:當咱們從一個模塊中引入一個變量的時候,若是當前文件中出現了崇明的變量時,會覆蓋掉模塊引入的哪一個變量。
因此要切記,不能夠重名,不只僅變量名不要重複,咱們本身建立的py文件的名字不要和系統內置的模塊重名,不然,引入的模塊都是python內置的模塊。
 
那有⼀種 特殊的寫法: from xxx import *  咱們說此時是把模塊中的全部內容都導入.  注意, 若是模塊中 沒有寫出__all__ 則默認全部內容都導入. 若是寫了了__all__ 此時導入的內容就是在__all__列表 中列出來的全部名字
 
# haha.py
__all__ = ["money", "eat"]
money = 100
def eat():    
    print("我是吃")
def drink():    
    print("我是呵呵")


# test.py
from haha import *
eat()
print(money)
drink() # 報錯
相關文章
相關標籤/搜索