0、init.py
在Python工程里,當(dāng)python檢測(cè)到一個(gè)目錄下存在__init__.py文件時(shí),python就會(huì)把它當(dāng)成一個(gè)模塊(module)。Module跟C++的命名空間和Java的Package的概念很像,都是為了科學(xué)地組織化工程,管理命名空間。
init.py可以是一個(gè)空文件,也可以有非常豐富的內(nèi)容。本文將舉一個(gè)非常簡(jiǎn)單的例子,來(lái)介紹__init__.py的用法;在本文的最后,我將會(huì)再簡(jiǎn)單介紹__init__.py的設(shè)計(jì)理念。
1、一個(gè)普通的四則運(yùn)算模塊
在不利用__init__.py的情況下,我們來(lái)看一個(gè)四則運(yùn)算的例子。我們的工程目錄結(jié)構(gòu)如下圖所示:
四則運(yùn)算例子的工程目錄結(jié)構(gòu)
如上圖,其中,main.py是程序入口,我們用了不同的方式來(lái)import四則運(yùn)算的各個(gè)子模塊。arithmetic模塊實(shí)現(xiàn)四則運(yùn)算;為了展示需要,我們將加減乘除四種運(yùn)算分別放在不同的代碼中。
每個(gè)文件的代碼如下:
#
# @file main.py
#
import arithmetic.add
import arithmetic.sub as sub
from arithmetic.mul import mul
from arithmetic import dev
def letscook(x, y, oper):
r = 0
if oper == "+":
r = arithmetic.add.add(x, y)
elif oper == "-":
r = sub.sub(x, y)
elif oper == "*":
r = mul(x, y)
else:
r = dev.dev(x, y)
print("{} {} {} = {}".format(x, oper, y, r))
x, y = 3, 8
letscook(x, y, "+")
letscook(x, y, "-")
letscook(x, y, "*")
letscook(x, y, "/")
#
# @file add.py
#
def add(a, b):
return a + b
#
# @file sub.py
#
def sub(a, b):
return a - b
#
# @file mul.py
#
def mul(a, b):
return a * b
#
# @file dev.py
#
def dev(a, b):
return a / b
從代碼可以看出,為了使用arithmetic中的某個(gè)子模塊(main.py中我們展示了四種不同的方式),我們必須使用非常繁瑣的import語(yǔ)句;在使用的時(shí)候,也有可能需要使用非常繁瑣的表達(dá)式。如果我們?cè)诓煌牡胤绞褂胊rithmetic的子模塊,都需要寫這么繁瑣的import或者使用表達(dá)式,你可能會(huì)覺(jué)得心累。這就是為什么我們需要利用__init__.py來(lái)簡(jiǎn)化我們的使用。
2、利用__init__.py
還是第1小節(jié)中的工程目錄結(jié)構(gòu),實(shí)現(xiàn)同樣的功能,我們?cè)赺_init__.py中編寫了一些代碼;同樣,我們對(duì)main.py進(jìn)行了一些適當(dāng)?shù)男薷摹?/p>
修改后__init__.py和main.py的代碼如下:
#
# @file main.py
#
import arithmetic as a4
def letscook(x, y, oper):
r = 0
if oper == "+":
r = a4.add(x, y)
elif oper == "-":
r = a4.sub(x, y)
elif oper == "*":
r = a4.mul(x, y)
else:
r = a4.dev(x, y)
print("{} {} {} = {}".format(x, oper, y, r))
x, y = 3, 8
letscook(x, y, "+")
letscook(x, y, "-")
letscook(x, y, "*")
letscook(x, y, "/")
#
# @file __init__.py
#
import arithmetic.add
import arithmetic.sub
import arithmetic.mul
import arithmetic.dev
add = arithmetic.add.add
sub = arithmetic.sub.sub
mul = arithmetic.mul.mul
dev = arithmetic.dev.dev
在__init__.py中, 我們import了arithmetic下的所有子模塊,并在__init__.py中給各個(gè)子模塊的核心功能取了新的名字,作為arithmetic模塊的變量。所以我們?cè)趍ain.py中import了arithmetic模塊之后,就可以直接進(jìn)行使用了。如果你使用from arithmetic import * 語(yǔ)句,那么我們就可以使用add、sub、mul、dev,連a4都省了。
3、init.py的設(shè)計(jì)原則
init.py的原始使命是聲明一個(gè)模塊,所以它可以是一個(gè)空文件。在__init__.py中聲明的所有類型和變量,就是其代表的模塊的類型和變量,第2小節(jié)就是利用這個(gè)原理,為四則運(yùn)算的4個(gè)子模塊聲明了新的變量。我們?cè)诶胈_init__.py時(shí),應(yīng)該遵循如下幾個(gè)原則:
A、不要污染現(xiàn)有的命名空間。模塊一個(gè)目的,是為了避免命名沖突,如果你在種用__init__.py時(shí)違背這個(gè)原則,是反其道而為之,就沒(méi)有必要使用模塊了。
B、利用__init__.py對(duì)外提供類型、變量和接口,對(duì)用戶隱藏各個(gè)子模塊的實(shí)現(xiàn)。一個(gè)模塊的實(shí)現(xiàn)可能非常復(fù)雜,你需要用很多個(gè)文件,甚至很多子模塊來(lái)實(shí)現(xiàn),但用戶可能只需要知道一個(gè)類型和接口。就像我們的arithmetic例子中,用戶只需要知道四則運(yùn)算有add、sub、mul、dev四個(gè)接口,卻并不需要知道它們是怎么實(shí)現(xiàn)的,也不想去了解arithmetic中是如何組織各個(gè)子模塊的。由于各個(gè)子模塊的實(shí)現(xiàn)有可能非常復(fù)雜,而對(duì)外提供的類型和接口有可能非常的簡(jiǎn)單,我們就可以通過(guò)這個(gè)方式來(lái)對(duì)用戶隱藏實(shí)現(xiàn),同時(shí)提供非常方便的使用。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-532742.html
C、只在__init__.py中導(dǎo)入有必要的內(nèi)容,不要做沒(méi)必要的運(yùn)算。像我們的例子,import arithmetic語(yǔ)句會(huì)執(zhí)行__ini__.py中的所有代碼。如果我們?cè)赺_init__.py中做太多事情,每次import都會(huì)有額外的運(yùn)算,會(huì)造成沒(méi)有必要的開(kāi)銷。一句話,init.py只是為了達(dá)到B中所表述的目的,其它事情就不要做啦。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-532742.html
到了這里,關(guān)于Python 中 __init__.py 文件用法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!