<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python入門系列15 - 史上最詳細(xì)的包和模塊import講解篇

          共 6818字,需瀏覽 14分鐘

           ·

          2019-08-29 09:07

          Python入門系列15

          dcab4e86f4a8dbaf1ea9fdaa6212e53d.webp

          史上最詳細(xì)的包和模塊import講解篇


          本篇文字圖片較多,閱讀時(shí)間不詳,能否讀完,純看你有沒有學(xué)習(xí)的心了?。?!


          1

          前言


          在大量的代碼設(shè)計(jì)中,我們不可能將所有代碼都寫在一個(gè).py文件,所以有了包、模塊,而為了代碼可以重復(fù)利用(復(fù)用性),就有了類、函數(shù)的概念。類和函數(shù)在下次介紹。


          2

          python中的包


          python中的包,對(duì)應(yīng)到計(jì)算機(jī)中,可以理解為文件夾,但是文件夾下必須有一個(gè)名為__init__.py的文件,若沒有此文件,python則會(huì)認(rèn)為其只是一個(gè)普通的文件夾。

          打開pycharm,創(chuàng)建一個(gè)包,如下:

          bbe1cec32ce85bd2238227479a23bf79.webp

          cb6e0e27ca14e7093631bb8b15adbb22.webp


          3

          python中的模塊


          python中的模塊就非常好理解了,實(shí)際上,之前所有的.py文件,我們都可以稱之為一個(gè)模塊。單獨(dú)的一個(gè)py文件就是一個(gè)模塊。

          3a8905d23a76ab3722d88e789558d70f.webp

          6b2b7eb9f7bca27262057a1b759fdeec.webp

          test1和test2不同區(qū)別就是test2是和package這個(gè)包是同級(jí)目錄,而test1是屬于package包的。


          再來(lái)看下總的概念:

          3c021b8dc2c780d974f9efb938acea2a.webp


          4

          包和模塊的引入


          1.模塊處于同級(jí)目錄(并且不在包下

          當(dāng)我們想在一個(gè)模塊中使用另一個(gè)模塊中的變量時(shí),如何操作呢?test2、test3處于同一級(jí)目錄。

          6a828cda3096e5bb680ce6f8226c29c2.webp


          我想在test3中引入test2的變量,test2.py中有個(gè)變量a = 2。

          30c83441e80d0848bad604876ead733a.webp

          f0a86a66590ca5b99ec0b6edcb653743.webp

          dc0eb072af8c0d526f8f90798f1a79c1.webp


          如上所示,只需要在當(dāng)前模塊,用import語(yǔ)句,即可導(dǎo)入模塊,具體使用的時(shí)候需要用模塊的名字.變量。

          import 后面必須是模塊的名稱!------> import modul name


          還有一種寫法如下圖pycharm中:

          adc73a0ee3d015aa6a0c909ab02790d0.webp

          如上所示,只需要在當(dāng)前模塊,? ? ?from 模塊名字 import? 變量? ? ?


          2.模塊處于同級(jí)目錄(在同一包下

          來(lái)看下,test1,test4都屬于package包下的模塊。

          8b5a2f8d6c430112be0b9615116b3991.webp


          test1.py中有著字符串a(chǎn) = 'I am success!'

          9b6fd1302b01ce67804b698e43b12e68.webp


          在test4.py中引用test1.py中的a,如何引用呢?

          可以看到如下:

          bca7594b632522df941b9b6db1af4007.webp


          關(guān)鍵語(yǔ)法:import?包名.模塊名?as?別名


          但是!?。。。。?!如果我們脫離pycharm,找到本機(jī)相應(yīng)的python目錄,通過cmd來(lái)運(yùn)行下,看下效果如何:


          994492240b38d0e7f34b3db326ab6eeb.webp

          8eed6b41a14bd15fee03ee10bd0d2fe2.webp


          可以清晰的看到上圖,通過命令行模式執(zhí)行就會(huì)報(bào)錯(cuò)!錯(cuò)誤顯示模塊沒有被找到:沒有模塊叫'package'。這是為什么呢?在pycharm中通過右鍵run as運(yùn)行test4,可以看到控制臺(tái)成功輸出,而本地調(diào)用命令行的形式就報(bào)錯(cuò)了!


          打開pycharm的setting,搜索 python console,右側(cè)其中有一項(xiàng),add content roots to pythonpath,默認(rèn)pycharm是勾選上此項(xiàng)的。此項(xiàng)的意思是將內(nèi)容的根路徑加到python的環(huán)境變量路徑下。

          a16ac65d8d2b3b9d4ec570a39922964d.webp

          可以看到上圖下面代碼塊里寫著一堆代碼,正是這段代碼,我們才可以在pycharm中正確運(yùn)行。


          我們可以在test1.py里來(lái)看下sys.path,順便打印看下結(jié)果。

          8bfb88bb971015c09339a6f1c7a1eeb3.webp


          pycharm控制臺(tái)輸出:

          ['F:\\pycharm\\python14\\package',?'F:\\pycharm\\python14',?
          'D:\\python3.6\\python36.zip',?
          'D:\\python3.6\\DLLs',?'D:\\python3.6\\lib',?'D:\\python3.6',?
          'C:\\Users\\sy\\AppData\\Roaming\\Python\\Python36\\site-packages',?
          'D:\\python3.6\\lib\\site-packages',?
          'D:\\python3.6\\lib\\site-packages\\win32',?
          'D:\\python3.6\\lib\\site-packages\\win32\\lib',
          ?'D:\\python3.6\\lib\\site-packages\\Pythonwin']

          實(shí)際通過命令行輸出,應(yīng)該沒有'F:\\pycharm\\python14' 這一項(xiàng),因?yàn)檫@一項(xiàng)是pycharm中setting自動(dòng)加上的!

          實(shí)際控制臺(tái)輸出:

          ['F:\\pycharm\\python14\\package',
          'D:\\python3.6\\python36.zip',?
          'D:\\python3.6\\DLLs',?'D:\\python3.6\\lib',?'D:\\python3.6',?
          'C:\\Users\\sy\\AppData\\Roaming\\Python\\Python36\\site-packages',?
          'D:\\python3.6\\lib\\site-packages',?
          'D:\\python3.6\\lib\\site-packages\\win32',?
          'D:\\python3.6\\lib\\site-packages\\win32\\lib',
          ?'D:\\python3.6\\lib\\site-packages\\Pythonwin']


          sys.path是一個(gè)list。默認(rèn)情況下python導(dǎo)入文件或者模塊的話,他會(huì)先在sys.path里找模塊的路徑。如果沒有的話,程序就會(huì)報(bào)錯(cuò)。可以看到,sys路徑下有package的包名,而沒有test4.py中引用test1.py模塊。


          而pycharm能夠成功運(yùn)行,正是因?yàn)樗呀?jīng)幫我們把項(xiàng)目的根路徑添加到了python的環(huán)境變量中。所以我們仿照其類似寫法也可以完成!


          解決方案:

          這里不得不說幾個(gè)重要的python自帶模塊了,如下:

          ①?

          __file__   : python模塊自身的名稱

          pycharm打印下__file__:

          可以看到pycharm會(huì)將模塊的絕對(duì)路徑輸出到控制臺(tái)上。

          ab8849639bb898458f84338a7bff0fca.webp


          在用命令行執(zhí)行下看看:

          b6d187f32d19e958f27fa92d4f95b45e.webp


          python額外小知識(shí):可以看到上圖有一個(gè)__pycache__的文件夾,這個(gè)文件夾在pycharm的目錄中,我們是看不到的,那么此文件夾的意義何在呢?點(diǎn)進(jìn)去看下:

          e9f1d2524feaa7463181aacc77353c5b.webp

          Python程序運(yùn)行時(shí)不需要編譯成二進(jìn)制代碼,而直接從源碼運(yùn)行程序,簡(jiǎn)單來(lái)說是,Python解釋器將源碼轉(zhuǎn)換為字節(jié)碼,然后再由解釋器來(lái)執(zhí)行這些字節(jié)碼。而解釋器的具體工作:?

          1、完成模塊的加載和鏈接。

          2、將源代碼編譯為PyCodeObject對(duì)象(即字節(jié)碼),寫入內(nèi)存中,供CPU讀取。

          3、從內(nèi)存中讀取并執(zhí)行,結(jié)束后將PyCodeObject寫回硬盤當(dāng)中,也就是復(fù)制到.pyc或.pyo文件中,以保存當(dāng)前目錄下所有腳本的字節(jié)碼文件。

          4、若再次執(zhí)行該腳本,它先檢查【本地是否有上述字節(jié)碼文件】和【該字節(jié)碼文件的修改時(shí)間是否在其源文件之后】,是就直接執(zhí)行,否則重復(fù)上述步驟。

          第一次執(zhí)行代碼的時(shí)候,Python解釋器已經(jīng)把編譯的字節(jié)碼放在__pycache__文件夾中,這樣以后再次運(yùn)行的話,如果被調(diào)用的模塊未發(fā)生改變,那就直接跳過編譯這一步,直接去__pycache__文件夾中去運(yùn)行相關(guān)的 *.pyc 文件,大大縮短了項(xiàng)目運(yùn)行前的準(zhǔn)備時(shí)間。


          CSDN來(lái)源:


          https://blog.csdn.net/index20001/article/details/73501375



          繼續(xù)回歸正題:


          import?sys,os ??:? sys ,os模塊是python系統(tǒng)自帶模塊

          os模塊:operate system 操作系統(tǒng)的意思,一般可以通過調(diào)用此模塊來(lái)對(duì)系統(tǒng)進(jìn)行相關(guān)操作

          sys 模塊:system 系統(tǒng)的意思,通過此模塊來(lái)實(shí)現(xiàn)對(duì)python自定義包和模塊的導(dǎo)入


          有了以上兩個(gè)知識(shí)點(diǎn),我們可以對(duì)test4.py進(jìn)行如下操作:

          import?sys,os

          print(__file__)
          print(os.path.abspath(__file__))
          print(os.path.dirname(os.path.abspath(__file__)))
          print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


          因?yàn)閜ycharm會(huì)對(duì)__file__進(jìn)行路徑補(bǔ)充,所以我們用命令行來(lái)執(zhí)行test4.py:

          9ae0a12672be2a96b844ca3cb8017023.webp


          可以看到上圖結(jié)果:

          __file__?????????????模塊名字
          test4.py???????????
          os.path.abspath(__file__)?????模塊名字的絕對(duì)路徑
          F:\pycharm\python14\package\test4.py
          os.path.dirname(os.path.abspath(__file__))????模塊的包名絕對(duì)路徑
          F:\pycharm\python14\package


          os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
          F:\pycharm\python14???????????????????????????項(xiàng)目本身的絕對(duì)路徑


          通過最后一步,我們可以將項(xiàng)目本身的路徑直接拼入python的sys下

          base_path?=?os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
          sys.path.append(base_path)


          驗(yàn)證究竟有沒有加到我們的python環(huán)境變量中,最終代碼為:

          import?sys,?os

          print(sys.path)
          print(__file__)
          print(os.path.abspath(__file__))
          print(os.path.dirname(os.path.abspath(__file__)))
          print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
          base_path?=?os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
          sys.path.append(base_path)
          print(sys.path)


          通過命令行執(zhí)行來(lái)看下:

          04d3b8ba60f7dee78f7e4f54f7b5a7ce.webp


          有了以上的所有操作步驟,我們可以完美的將test1.py的a變量引入test4.py中了!來(lái)看下命令執(zhí)行:


          import?sys,?os
          base_path?=?os.path.dirname(os.path.dirname(
          ????????????????????????????os.path.abspath(__file__)))
          sys.path.append(base_path)
          ----------------??sys拼接?一定要在自定義包引入之前定義???----------------------------------
          import?package.test1?as?test1???????注意import的順序。
          print(test1.a)


          78af755c7ce1e444cc69e7db7f63a804.webp

          成功!

          寫到這里涉及的知識(shí)點(diǎn)就已經(jīng)這么多了。。。繼續(xù)寫。。。


          3.包處于同級(jí)目錄(包和包同級(jí),包1下的模塊引入包2下的模塊變量

          0f70427182547d5cf6431f09c62ba460.webp

          可以看到,通過from test3 import c,pycharm中是正常輸出的,控制臺(tái)是報(bào)錯(cuò)的!原因?qū)嶋H和“2.模塊處于同級(jí)目錄(在同一包下”的解釋是一樣的,只需要在引入自定義包之前,將我們項(xiàng)目的根路徑加到python的系統(tǒng)變量中即可。


          4.模塊處于不同級(jí)目錄(包和模塊同級(jí),模塊引入包下模塊的變量

          c1446a26fb148ec3c36163ae4c2af8ed.webp

          ecf69b994383990e34f825d27e1ccd29.webp

          c69cf74c3a7215b0c8309abdcc555c53.webp

          若屬于3的情況,可以看到,不需要對(duì)python系統(tǒng)進(jìn)行sys.append,可以正常使用import 或者 from 語(yǔ)句進(jìn)行導(dǎo)入。


          5.模塊處于不同級(jí)目錄(包和模塊同級(jí),包下模塊引入與包模塊同級(jí)的變量

          test3.py 中有:

          c = 123455666

          在packeage下的test1.py調(diào)用:

          fcc1155aa9cb09159d1c9777a1ee6ddb.webp


          可以看到,通過from test3 import c,pycharm中是正常輸出的,控制臺(tái)是報(bào)錯(cuò)的!原因?qū)嶋H和“2.模塊處于同級(jí)目錄(在同一包下)”的解釋是一樣的,只需要在引入自定義包之前,將我們項(xiàng)目的根路徑加到python的系統(tǒng)變量中即可。


          import?sys,?os
          base_path?=?os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
          sys.path.append(base_path)
          from?test3?import?c
          print(c)


          c404989161b3586bfe5573a68df9fd5e.webp


          5

          模塊之前的相對(duì)引入


          什么叫相對(duì)引入呢?相對(duì)路徑大家可能聽說過,相對(duì)引入和相對(duì)路徑是一個(gè)道理的,比如 .代表的是當(dāng)前目錄,..代表的是上級(jí)目錄,此處的寫法就是相對(duì)路徑,相對(duì)于某個(gè)文件來(lái)說,即相對(duì)!


          實(shí)際上,在2.模塊處于同級(jí)目錄(在同一包下)中,還有一種相對(duì)引入的寫法,但是對(duì)于test4.py引入test1.py來(lái)說,不能直接運(yùn)行test4.py,否則會(huì)報(bào)錯(cuò)。來(lái)看下:

          dfa9f2926f1c76476c3d5b07f94a8411.webp


          test1.py中有個(gè)a字符串:

          test1.py
          a?=?'I?am?success?!'


          test4.py中,我用from .test1 import a來(lái)引入test1.py的變量a,注意,包下同級(jí)目錄,我使用的是.test1 ?!?。?!

          test4.py

          from?.test1?import?a
          b?=?a?+?'I?am?test4.py?import?.test1'


          如果此時(shí)我直接將test4.py運(yùn)行,并且打印b,就會(huì)報(bào)錯(cuò)!

          e9e2e3e14949eee4cfe3c434fd5c1c03.webp

          ModuleNotFoundError:?No?module?named?'__main__.test1';?'__main__'?is?not?
          a?package


          如果此時(shí),我通過test2.py間接行調(diào)用test4.py中的b


          from package.test4 import b
          print(b)


          無(wú)論是pycharm還是命令行,都是有成功運(yùn)行的:

          8fe5e287432d940e1aa3c7aa3c02fa9c.webp

          也就是說python對(duì)于相對(duì)引入來(lái)說,主動(dòng)引入的函數(shù)不能作為主體去運(yùn)行!


          6

          pycharm中可能會(huì)遇到的import報(bào)錯(cuò)


          有人可能會(huì)遇到,當(dāng)一個(gè)新項(xiàng)目導(dǎo)入到pycharm中,python代碼的import有可能會(huì)報(bào)錯(cuò),可以將項(xiàng)目設(shè)置為根路徑,這樣import錯(cuò)誤即可消失,操作如下:

          0e8f8a3fbcd75b47fab1d412102df52f.webp


          7

          包和模塊自身的額外小知識(shí)點(diǎn)


          1. 關(guān)于包下的 __init__.py

          init,中文意思是初始化的意思,而__init__.py實(shí)際上就是作為包名來(lái)配合的,當(dāng)我們調(diào)用一個(gè)包時(shí),第一步python就會(huì)去調(diào)用__init__.py模塊,所以,經(jīng)常我們可以將包下的__init__.py中放入一些需要初始化的操作。

          舉個(gè)例子:

          e28546b737991b0bb46b723f8801dfb5.webp

          __init__.py:
          init_a = 'I am __init__.py'
          print(init_a)

          在package包下定義了初始化的字符串。


          而test2.py調(diào)用package下的test1.py中的a變量時(shí):

          test2.py:
          from
          package.test1 import a
          print(a)
          test1.py:
          a = 'I am success !'


          可以看到下圖運(yùn)行結(jié)果,先輸出了初始化模塊中的字符串:

          14efed84d194954fe727289a41b3750d.webp


          2. 關(guān)于模塊中的限定變量寫法


          依然是test2.py引入test1.py的變量:

          897d7a8a70814528b1e4c7c395db5825.webp

          test2.py:
          from
          package.test1 import a,b,c
          print(a)
          print(b)
          print(c)
          test1.py:
          __all__ = ['a','b']
          a = 'I am success !'
          b = 'I am fail !'
          c = 'I am fuc*** ?you!!! !'

          在test2中引入test1通過import單獨(dú)引入三個(gè)變量,運(yùn)行結(jié)果:

          a90858fccc319958ea6aea042eb9dfc7.webp


          若將import 后面改成* ,則會(huì)限制變量。

          3f8b5548ee5e7a3c78aa27a30c582598.webp

          而此處所說,就是因?yàn)樵趖est1.py中有著__all__ = []? ,這樣的寫法可以限定住import * 的限制,test4.py import *時(shí),則會(huì)被限制住罵人的語(yǔ)句!


          8

          import 模塊的萬(wàn)金油方法


          上面說了這么多種情況,如果你實(shí)在是記不住,那么請(qǐng)記住一點(diǎn),萬(wàn)金油的import方式,就是在你所有模塊的入口模塊處,以下面代碼為例,將你項(xiàng)目本身的絕對(duì)路徑拼入到python 的系統(tǒng)path下,這樣自定義的包一定不會(huì)出錯(cuò)?。?!

          import sys, os
          base_path = os.path.dirname(os.path.dirname(
          os.path.abspath(__file__)))
          sys.path.append(base_path)




          以上,就是史上最最最最最最,超超超超詳細(xì)的python模塊和包的引入詳解!?。。?!歡迎轉(zhuǎn)載!??!歡迎爆文?。。?!

          瀏覽 194
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  四虎影库男人精品 | 天天干天天射综合 | 欧美色图视频一区 | 亚洲无码电影在线观看 | 欧美亚洲天堂网 |