Python包、模塊、類(lèi)和代碼文件目錄的管理方案

1.要解決的問(wèn)題

Python在語(yǔ)義中存在著包、模塊、類(lèi)(當(dāng)然還有函數(shù))這幾個(gè)概念。

在編寫(xiě)Python代碼時(shí),我們需要管理代碼的文件目錄結(jié)構(gòu)

這時(shí)候會(huì)遇到這樣一種情況:

1.由于Python一個(gè)文件算一個(gè)模塊,一個(gè)帶__init__.py的目錄算一個(gè)包

2.而為了控制代碼文件不要過(guò)大,我們需要的是一個(gè)類(lèi)(幾個(gè)類(lèi)或加些許函數(shù))分配一個(gè)文件

3.這時(shí)候會(huì)出現(xiàn)類(lèi)似這樣的語(yǔ)句:

#第一種

importpackage_a.class_a_fileascaf

a=caf.ClassA()

#第二種

formpackage_a.class_a_file import *

a=ClassA()

#另外幾種就不意義列舉了...

以上除了直觀上可以看出import過(guò)長(zhǎng)外,隱藏的另一點(diǎn)是我們是希望一個(gè)類(lèi)用一個(gè)文件,在使用多個(gè)相關(guān)類(lèi)的時(shí)候就必須寫(xiě)很多import。(注:我們可不想一堆代碼扎堆,弄出一個(gè)超大代碼文件。)

2.解決方案要達(dá)到的效果

#文件目錄結(jié)構(gòu)

#|--demo.py

#|--package_a

#?? |--__init__.py

#?? |--class_a.py??#類(lèi)ClassA

#?? |--class_b.py??#類(lèi)ClassB和函數(shù)func_b()

#demo.py中可以直接使用

from package_a import *

a=ClassA()

b=ClassB()

func_b()

由于Python里一個(gè)帶__init__.py的目錄算一個(gè)包,所以利用這一機(jī)制,把類(lèi)文件放在包里,用包來(lái)管理類(lèi)。

注:在Python里“包是模塊,而模塊不是包”。用system.modules可以取到的名字是包和模塊都有的,而用__package__卻能很好的區(qū)分包和模塊。也就是“包其實(shí)是一種特殊的模塊”。

3.解決方案

這就是解決方案的文件base.py,代碼很短:

import sys

_packet_={}

#它是個(gè)裝飾器,item是類(lèi),或者函數(shù)

def export(item):

#獲取item的模塊對(duì)象

module=sys.modules[item.__module__]

#由模塊對(duì)象得到包對(duì)象

package=sys.modules[module.__package__]

#把item添加到包的__dict__里

package.__dict__[item.__name__]=item

#生成所有使用該解決方案的包的__all__變量,并把導(dǎo)出的item添加進(jìn)去

ifnotpackage.__name__in_packet_:

_packet_[package.__name__]=[]

_packet_[package.__name__].append(item.__name__)

#原封不動(dòng)地把item返回

returnitem

#它是個(gè)函數(shù),在包__init__.py里用于獲取__all__

def packet(name):

ifnotnamein_packet_:

_packet_[name]=[]

return_packet_[name]

代碼用意我寫(xiě)在注釋里了,就是以裝飾器來(lái)把類(lèi)添加到包的__dict__和__all__里。__all__需要利用packet在包里生成,不這么做只會(huì)使得from package_name import * 后不能找到類(lèi),需要寫(xiě)具體的類(lèi)名from package_name import ClassA。

4.使用解決方案

先來(lái)看下使用解決方案后的目錄結(jié)構(gòu):

#文件目錄結(jié)構(gòu)(使用后結(jié)構(gòu)只多了base.py)

#|--base.py

#|--demo.py

#|--package_a

#?? |--__init__.py

#?? |--class_a.py??#類(lèi)ClassA

#?? |--class_b.py??#類(lèi)ClassB和函數(shù)func_b()

代碼處就需要做到以下幾點(diǎn):

1.關(guān)于被導(dǎo)出的類(lèi)文件里應(yīng)該怎么做,這里以class_b.py為例子:

# ./package_a/class_b.py

#1.需要導(dǎo)入base

importbase

#2.使用export裝飾器,裝飾要導(dǎo)出的類(lèi)或函數(shù)

@base.export

classClassB:pass

#2.同樣的export可以導(dǎo)出函數(shù)

@base.export

def func_b():

print('func_b')

2.使用了導(dǎo)出功能的包要做什么,這里以package_a包為例:

# ./package_a/__init__.py

#1.導(dǎo)入base

importbase

#2.導(dǎo)入將要導(dǎo)出的子模塊,需要具體模塊名字的形式,from . import * 不可用

from.importclass_a,class_b

#3.用packet初始化__all__,這個(gè)可選,主要是看要不要支持 from 的用 * 導(dǎo)入

__all__=base.packet(__name__)

#4.這個(gè)是可選的,因?yàn)槿绻昧薩_all__會(huì)影響from *。可以用export把__init__.py里的項(xiàng),加入__all__

@base.export

def pafunc():

print('pafunc')

5.總結(jié)

使用該解決方案可以歸納為兩點(diǎn):

1.用@base.export標(biāo)記要導(dǎo)出的類(lèi)或函數(shù)

2.在包__init__.py里初始化__all__ = base.packet(__name__)

3.(說(shuō)好的只有兩點(diǎn)呢?)其實(shí)第2點(diǎn)是可選的,不過(guò)最好加上。而在包的__init__.py里導(dǎo)入子模塊才是真正的第2點(diǎn)。不然子模塊不會(huì)被載入,也談不上導(dǎo)出了。

最后,demo.py里可以這么寫(xiě),和預(yù)期的效果一樣:)

# ./demo.py

from package_a import *

a=ClassA()# 上面的實(shí)例沒(méi)有給出,不過(guò)假設(shè)有ClassA在class_a.py里的

b=ClassB()

func_b()學(xué)好python你需要一個(gè)良好的環(huán)境,一個(gè)優(yōu)質(zhì)的開(kāi)發(fā)交流群,群里都是那種相互幫助的人才是可以的,我有建立一個(gè)python學(xué)習(xí)交流群,在群里我們相互幫助,相互關(guān)心,相互分享內(nèi)容,這樣出問(wèn)題幫助你的人就比較多,群號(hào)是304加上050最後799,這樣就可以找到大神聚合的群,如果你只愿意別人幫助你,不愿意分享或者幫助別人,那就請(qǐng)不要加了,你把你會(huì)的告訴別人這是一種分享。無(wú)論是學(xué)習(xí)任何一門(mén)語(yǔ)言,基礎(chǔ)知識(shí),就是基礎(chǔ)功非常的重要,找一個(gè)有豐富編程經(jīng)驗(yàn)的老師或者師兄帶著你會(huì)少走很多彎路, 你的進(jìn)步速度也會(huì)快很多,無(wú)論我們學(xué)習(xí)的目的是什么,不得不說(shuō)Python真的是一門(mén)值得你付出時(shí)間去學(xué)習(xí)的優(yōu)秀編程

語(yǔ)言。

感覺(jué)寫(xiě)的好,對(duì)你有幫助,就點(diǎn)個(gè)贊唄,別光只收藏哈.~( ̄▽?zhuān)?~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 類(lèi) 類(lèi)的概念在許多語(yǔ)言中出現(xiàn),很容易理解。它將數(shù)據(jù)和操作進(jìn)行封裝,以便將來(lái)的復(fù)用。 模塊 模塊,在Python可理...
    隨風(fēng)化作雨閱讀 1,917評(píng)論 0 5
  • Python類(lèi)、模塊、包的區(qū)別 類(lèi)類(lèi)的概念在許多語(yǔ)言中出現(xiàn),很容易理解。它將數(shù)據(jù)和操作進(jìn)行封裝,以便將來(lái)的復(fù)用。模...
    周倜吉閱讀 5,312評(píng)論 0 3
  • 朋友的孩子是個(gè)非常優(yōu)秀的女生,從小到大,年級(jí)第一名是她的標(biāo)榜,各類(lèi)比賽也是屢屢得獎(jiǎng),就連大學(xué),研究生都是保送,長(zhǎng)的...
    榕莎莎閱讀 523評(píng)論 0 1
  • 單曲循環(huán)了三天的歌 今天終于去看了電影 有點(diǎn)浮夸 可是感情很細(xì)膩 很細(xì)微 很純真 很好看 還有 今天下了初...
    MaoMaoMei閱讀 316評(píng)論 5 0
  • 這是一本很短的戲劇劇本,大概講述了一個(gè)出軌流言的故事。 胡立安收養(yǎng)埃內(nèi)斯托為養(yǎng)子,卻傳出埃內(nèi)斯托與其養(yǎng)母,也就是自...
    隨風(fēng)銘記閱讀 2,008評(píng)論 0 1