溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python基礎(chǔ)之模塊怎么使用

發(fā)布時(shí)間:2023-05-17 11:20:32 來(lái)源:億速云 閱讀:74 作者:zzz 欄目:編程語(yǔ)言

這篇文章主要介紹“Python基礎(chǔ)之模塊怎么使用”,在日常操作中,相信很多人在Python基礎(chǔ)之模塊怎么使用問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Python基礎(chǔ)之模塊怎么使用”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

    一、模塊

    模塊可以看成是一堆函數(shù)的集合體。

    一個(gè)py文件內(nèi)部就可以放一堆函數(shù),因此一個(gè)py文件就可以看成一個(gè)模塊。

    如果這個(gè)py文件的文件名為module.py,模塊名則是module。

    1、模塊的四種形式

    在Python中,總共有以下四種形式的模塊:

    • 自定義模塊:如果你自己寫一個(gè)py文件,在文件內(nèi)寫入一堆函數(shù),則它被稱為自定義模塊,即使用python編寫的.py文件

    • 第三方模塊:已被編譯為共享庫(kù)或DLL的C或C++擴(kuò)展 ,如requests

    • 內(nèi)置模塊:使用C編寫并鏈接到python解釋器的內(nèi)置模塊 ,如time

    • 包(文件夾):把一系列模塊組織到一起的文件夾(注:文件夾下有一個(gè)__init__.py文件,該文件夾稱之為包)

    2、為什么要用模塊?
    • 用第三方或者內(nèi)置的模塊是一種拿來(lái)主義,可以極大地提升開發(fā)效率。

    • 自定義模塊,將我們自己程序中用到的公共功能,寫入一個(gè)python文件,然后程序的各部分組件可以通過(guò)導(dǎo)入的方式來(lái)引用自定義模塊的功能。

    二、如何用模塊

    一般我們使用import和from...import...導(dǎo)入模塊。

    以下述spam.py內(nèi)的文件代碼為例。

    # spam.py
    print('from the spam.py')
    money = 1000
    def read1():
    print('spam模塊:', money)
    def read2():
    print('spam模塊')
    read1()
    def change():
    global money
    money = 0
    1、import 模塊名

    語(yǔ)法如下:

    import module1[, module2[,... moduleN]

    import導(dǎo)入的模塊,訪問(wèn)需要加前綴。

    import首次導(dǎo)入模塊發(fā)生了3件事:

    • 以模塊為準(zhǔn)創(chuàng)造一個(gè)模塊的名稱空間

    • 執(zhí)行模塊對(duì)應(yīng)的文件,將執(zhí)行過(guò)程中產(chǎn)生的名字都丟到模塊的名稱空間

    • 在當(dāng)前執(zhí)行文件中拿到一個(gè)模塊名

    注意:模塊的重復(fù)導(dǎo)入會(huì)直接引用之前創(chuàng)造好的結(jié)果,不會(huì)重復(fù)執(zhí)行模塊的文件。

    # run.py
    import spam # from the spam.py
    import spam
    money = 111111
    spam.read1() # 'spam模塊:1000'
    spam.change()
    print(spam.money) # 0
    print(money) # 111111
    導(dǎo)入重命名:smt變量指向span模塊的名稱空間
    # run.py
    import spam as sm
    money = 111111
    sm.money
    sm.read1() # 'spam模塊:1000'
    sm.read2
    sm.change()
    print(money) # 1000
    導(dǎo)入多個(gè)模塊
    import spam, time, os
    # 推薦使用下述方式
    import spam
    import time
    import os
    2、from 模塊名 import 具體的函數(shù)

    語(yǔ)法如下:

    from modname import name1[, name2[, ... nameN]]

    這個(gè)聲明不會(huì)把整個(gè)模塊導(dǎo)入到當(dāng)前的命名空間中,它只會(huì)將模塊里的一個(gè)或多個(gè)函數(shù)引入進(jìn)來(lái)。

    from...import...導(dǎo)入的模塊,訪問(wèn)不需要加前綴。

    from...import...首次導(dǎo)入模塊發(fā)生了3件事:

    • 以模塊為準(zhǔn)創(chuàng)造一個(gè)模塊的名稱空間

    • 執(zhí)行模塊對(duì)應(yīng)的文件,將執(zhí)行過(guò)程中產(chǎn)生的名字都丟到模塊的名稱空間

    • 在當(dāng)前執(zhí)行文件的名稱空間中拿到一個(gè)名字,該名字直接指向模塊中的某一個(gè)名字,意味著可以不用加任何前綴而直接使用

    • 優(yōu)點(diǎn):不用加前綴,代碼更加精簡(jiǎn)

    • 缺點(diǎn):容易與當(dāng)前執(zhí)行文件中名稱空間中的名字沖突

    # run.py
    from spam import money
    from spam import money,read1
    money = 10
    print(money) # 10
    rom … import * 語(yǔ)句:導(dǎo)入文件內(nèi)所有的功能:
    # spam.py
    __all__ = ['money', 'read1'] # 只允許導(dǎo)入'money'和'read1'
    
    # run.py
    from spam import * # 導(dǎo)入spam.py內(nèi)的所有功能,但會(huì)受限制于__all__
    money = 111111
    read1() # 'spam模塊:1000'
    change()
    read1() # 'spam模塊:0'
    print(money) # 111111
    3、循環(huán)導(dǎo)入

    以下情況會(huì)出現(xiàn)循環(huán)導(dǎo)入:

    # m1.py
    print('from m1.py')
    from m2 import x
    y = 'm1'
    # m2.py
    print('from m2.py')
    from m1 import y
    x = 'm2'

    可以使用函數(shù)定義階段只識(shí)別語(yǔ)法的特性解決循環(huán)導(dǎo)入的問(wèn)題,或從本質(zhì)上解決循環(huán)導(dǎo)入的問(wèn)題,但是最好的解決方法是不要出現(xiàn)循環(huán)導(dǎo)入。

    方案一:

    # m1.py
    print('from m1.py')
    def func1():
    from m2 import x
    print(x)
    y = 'm1'
    
    
    
    # m2.py
    print('from m2.py')
    def func1():
    from m1 import y
    print(y)
    x = 'm2'

    方案二:

    5、# m1.py
    print('from m1.py')
    y = 'm1'
    from m2 import x
    
    
    
    # m2.py
    print('from m2.py')
    x = 'm2'
    from m1 import y
    4、dir() 函數(shù)

    內(nèi)置的函數(shù) dir() 可以找到模塊內(nèi)定義的所有名稱。以一個(gè)字符串列表的形式返回:

    dir(sys)
    ['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
    '__package__', '__stderr__', '__stdin__', '__stdout__',
    '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
    '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
    'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
    'call_tracing', 'callstats', 'copyright', 'displayhook',
    'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
    'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
    'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
    'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
    'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
    'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
    'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
    'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
    'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
    'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
    'thread_info', 'version', 'version_info', 'warnoptions']

    如果沒(méi)有給定參數(shù),那么 dir() 函數(shù)會(huì)羅列出當(dāng)前定義的所有名稱:

    a = [1, 2, 3, 4, 5]
    import fibo
    fib = fibo.fib
    print(dir()) # 得到一個(gè)當(dāng)前模塊中定義的屬性列表
    # ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
    
    b = 5 # 建立一個(gè)新的變量 'a'
    print(dir())
    # ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b']
    del b # 刪除變量名a
    print(dir())
    # ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']

    三、模塊搜索路徑

    1、導(dǎo)入模塊時(shí)查找模塊的順序
    1、先從內(nèi)存中已經(jīng)導(dǎo)入的模塊中尋找

    如果我們?cè)谶\(yùn)行run.py文件的時(shí)候,快速刪除mmm.py文件,我們會(huì)發(fā)現(xiàn)文件會(huì)繼續(xù)運(yùn)行,而不會(huì)報(bào)錯(cuò),因?yàn)閙mm已經(jīng)被導(dǎo)入內(nèi)存當(dāng)中。如果我們?cè)僖淮芜\(yùn)行run.py時(shí)會(huì)報(bào)錯(cuò),因?yàn)閙mm.py已經(jīng)被刪除了。

    # test.py
    import m1 # 從m1.py文件中導(dǎo)入的,然后會(huì)生成m1模塊的名稱空間
    import time
    # 刪除m1.py文件,m1模塊的名稱空間仍然存在
    
    time.sleep(10)
    import m1 # 不報(bào)錯(cuò),一定不是從文件中獲取了m1模塊,而是從內(nèi)存中獲取的
    2、內(nèi)置的模塊

    驗(yàn)證先從內(nèi)置中找,不會(huì)先找自定義的time.py文件。

    # time.py
    print('from time.py')
    # run.py
    import time
    print(time) #
    3、環(huán)境變量sys.path中找(強(qiáng)調(diào):sys.path的第一個(gè)值是當(dāng)前執(zhí)行文件的所在的文件夾)
    import sys
    for n in sys.path:
    print(n)
    # C:\PycharmProjects\untitled\venv\Scripts\python.exe C:/PycharmProjects/untitled/hello.py
    # C:\PycharmProjects\untitled
    # C:\PycharmProjects\untitled
    # C:\Python\Python38\python38.zip
    # C:\Python\Python38\DLLs
    # C:\Python\Python38\lib
    # C:\Python\Python38
    # C:\PycharmProjects\untitled\venv
    # C:\PycharmProjects\untitled\venv\lib\site-packages

    如果mmm.py在C:\PycharmProjects\untitled\day16路徑下,而執(zhí)行文件路徑為C:\PycharmProjects\untitled,如果普通導(dǎo)入一定會(huì)報(bào)錯(cuò),我們可以把C:\PycharmProjects\untitled\day16添加到環(huán)境變量sys.path中,防止報(bào)錯(cuò)。

    # run.py
    import sys
    sys.path.append(r'C:\PycharmProjects\untitled\day16')
    print(sys.path)
    import mmm
    mmm.f1()
    2、搜索路徑以執(zhí)行文件為準(zhǔn)

    假設(shè)我們有如下目錄結(jié)構(gòu)的文件,文件內(nèi)代碼分別是:

    Python基礎(chǔ)之模塊怎么使用

    而hello和spam.py不是同目錄下的,因此run.py的環(huán)境變量無(wú)法直接找到m2,需要從文件夾導(dǎo)入

    from aa import spam
    print(spam.money)

    四、Python文件的兩種用途

    一個(gè)模塊被另一個(gè)程序第一次引入時(shí),其主程序?qū)⑦\(yùn)行。如果我們想在模塊被引入時(shí),模塊中的某一程序塊不執(zhí)行,我們可以用__name__屬性來(lái)使該程序塊僅在該模塊自身運(yùn)行時(shí)執(zhí)行。

    python文件總共有兩種用途,一種是執(zhí)行文件;另一種是被當(dāng)做模塊導(dǎo)入。

    每個(gè)模塊都有一個(gè)__name__屬性,當(dāng)其值是'__main__'時(shí),表明該模塊自身在運(yùn)行,否則是被引入。

    1、當(dāng)run.py運(yùn)行的時(shí)候,aaa.py被當(dāng)做引用模塊,它的__name__ == 'aaa'(模塊名),會(huì)執(zhí)行aaa.py中的f1()。

    # aaa.py
    x = 1
    def f1():
    print('from f1')
    f1()
    # run.py
    import aaa

    2、aaa.py被當(dāng)做可執(zhí)行文件時(shí),加上__name__ == '__main__',單獨(dú)運(yùn)行aaa.py才會(huì)執(zhí)行aaa.py中的f1()。 run.py運(yùn)行時(shí)可以防止執(zhí)行f1()。

    # aaa.py
    x = 1
    def f1():
    print('from f1')
    
    if __name__ == '__main__':
    f1()

    五、包

    包是一種管理 Python 模塊命名空間的形式,包的本質(zhì)就是一個(gè)含有.py的文件的文件夾。

    包采用"點(diǎn)模塊名稱"。比如一個(gè)模塊的名稱是 A.B, 那么他表示一個(gè)包 A中的子模塊 B 。

    目錄只有包含一個(gè)叫做 __init__.py 的文件才會(huì)被認(rèn)作是一個(gè)包。

    在導(dǎo)入一個(gè)包的時(shí)候,Python 會(huì)根據(jù) sys.path 中的目錄來(lái)尋找這個(gè)包中包含的子目錄。

    導(dǎo)入包發(fā)生的三件事:

    • 創(chuàng)建一個(gè)包的名稱空間

    • 由于包是一個(gè)文件夾,無(wú)法執(zhí)行包,因此執(zhí)行包下的.py文件,將執(zhí)行過(guò)程中產(chǎn)生的名字存放于包名稱空間中(即包名稱空間中存放的名字都是來(lái)自于.py)

    • 在當(dāng)前執(zhí)行文件中拿到一個(gè)名字aaa,aaa是指向包的名稱空間的

    導(dǎo)入包就是在導(dǎo)入包下的.py,導(dǎo)入m1就是導(dǎo)入m1中的__init__。

    1、兩種方式導(dǎo)入:
    • import ... :
      import item.subitem.subsubitem 這種導(dǎo)入形式,除了最后一項(xiàng),都必須是包,而最后一項(xiàng)則可以是模塊或者是包,但是不可以是類,函數(shù)或者變量的名字。

    • from ... import...:
      當(dāng)使用 from package import item 這種形式的時(shí)候,對(duì)應(yīng)的 item 既可以是包里面的子模塊(子包),或者包里面定義的其他名稱,比如函數(shù),類或者變量。

    Python基礎(chǔ)之模塊怎么使用

    2、import 導(dǎo)入包內(nèi)的模塊

    import 可以每次只導(dǎo)入一個(gè)包里面的特定模塊,他必須使用全名去訪問(wèn)。

    import aaa.bbb.m3
    print(aaa.bbb.m3.func3())

    import方式不能導(dǎo)入函數(shù)、變量:import aaa.bbb.m3.f3錯(cuò)誤

    3、from import方式:
    導(dǎo)入模塊內(nèi)具體的模塊

    這種方式不需要那些冗長(zhǎng)的前綴進(jìn)行訪問(wèn)

    from aaa.bbb import m3
    print(m3.func3())
    導(dǎo)入模塊內(nèi)具體的功能

    這種方式不需要那些冗長(zhǎng)的前綴進(jìn)行訪問(wèn)

    from aaa.bbb.m3 import func3
    print(func3())
    4、 絕對(duì)導(dǎo)入和相對(duì)導(dǎo)入
    絕對(duì)導(dǎo)入:
    # aaa/.py
    from aaa.m1 import func1
    from aaa.m2 import func2
    相對(duì)導(dǎo)入:
    • .代表當(dāng)前被導(dǎo)入文件所在的文件夾

    • ..代表當(dāng)前被導(dǎo)入文件所在的文件夾的上一級(jí)

    • ...代表當(dāng)前被導(dǎo)入文件所在的文件夾的上一級(jí)的上一級(jí)

    from .m1 import func1
    from .m2 import func2
    5、from...import *

    導(dǎo)入語(yǔ)句遵循如下規(guī)則:如果包定義文件 __init__.py 存在一個(gè)叫做 __all__ 的列表變量,那么在使用 from package import * 的時(shí)候就把這個(gè)列表中的所有名字作為包內(nèi)容導(dǎo)入。

    這里有一個(gè)例子,在:file:sounds/effects/__init__.py中包含如下代碼:

    __all__ = ["echo", "surround", "reverse"]

    這表示當(dāng)你使用from sound.effects import *這種用法時(shí),你只會(huì)導(dǎo)入包里面這三個(gè)子模塊。

    六、軟件開發(fā)的目錄規(guī)范

    為了提高程序的可讀性與可維護(hù)性,我們應(yīng)該為軟件設(shè)計(jì)良好的目錄結(jié)構(gòu),這與規(guī)范的編碼風(fēng)格同等重要,簡(jiǎn)而言之就是把軟件代碼分文件目錄。假設(shè)你要寫一個(gè)ATM軟件,你可以按照下面的目錄結(jié)構(gòu)管理你的軟件代碼:

    ATM/
    |-- core/
    | |-- src.py # 業(yè)務(wù)核心邏輯代碼
    |
    |-- api/
    | |-- api.py # 接口文件
    |
    |-- db/
    | |-- db_handle.py # 操作數(shù)據(jù)文件
    | |-- db.txt # 存儲(chǔ)數(shù)據(jù)文件
    |
    |-- lib/
    | |-- common.py # 共享功能
    |
    |-- conf/
    | |-- settings.py # 配置相關(guān)
    |
    |-- bin/
    | |-- run.py # 程序的啟動(dòng)文件,一般放在項(xiàng)目的根目錄下,因?yàn)樵谶\(yùn)行時(shí)會(huì)默認(rèn)將運(yùn)行文件所在的文件夾作為sys.path的第一個(gè)路徑,這樣就省去了處理環(huán)境變量的步驟
    |
    |-- log/
    | |-- log.log # 日志文件
    |
    |-- requirements.txt # 存放軟件依賴的外部Python包列表,詳見https://pip.readthedocs.io/en/1.1/requirements.html
    |-- README # 項(xiàng)目說(shuō)明文件
    settings.py
    # settings.py
    import os
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    DB_PATH = os.path.join(BASE_DIR, 'db', 'db.txt')
    LOG_PATH = os.path.join(BASE_DIR, 'log', 'user.log')
    # print(DB_PATH)
    # print(LOG_PATH)
    common.py
    # common.py
    import time
    from conf import settings
    def logger(msg):
    current_time = time.strftime('%Y-%m-%d %X')
    with open(settings.LOG_PATH, mode='a', encoding='utf-8') as f:
    f.write('%s %s' % (current_time, msg))
    src.py
    # src.py
    from conf import settings
    from lib import common
    def login():
    print('登陸')
    def register():
    print('注冊(cè)')
    name = input('username>>: ')
    pwd = input('password>>: ')
    with open(settings.DB_PATH, mode='a', encoding='utf-8') as f:
    f.write('%s:%s\n' % (name, pwd))
    # 記錄日志。。。。。。
    common.logger('%s注冊(cè)成功' % name)
    print('注冊(cè)成功')
    def shopping():
    print('購(gòu)物')
    def pay():
    print('支付')
    def transfer():
    print('轉(zhuǎn)賬')
    func_dic = {
    '1': login,
    '2': register,
    '3': shopping,
    '4': pay,
    '5': transfer,
    }
    def run():
    while True:
    print("""
    1 登陸
    2 注冊(cè)
    3 購(gòu)物
    4 支付
    5 轉(zhuǎn)賬
    6 退出
    """)
    choice = input('>>>: ').strip()
    if choice == '6': break
    if choice not in func_dic:
    print('輸入錯(cuò)誤命令,傻叉')
    continue
    func_dic[choice]()
    run.py
    # run.py
    import sys
    import os
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)
    from core import src
    if __name__ == '__main__':
    src.run()

    到此,關(guān)于“Python基礎(chǔ)之模塊怎么使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI