PEP-0328 中文翻譯 By Lance Van

最近在做微信公眾平臺(tái)的后臺(tái)開發(fā),找到了一個(gè)Python的微信SDKwechat-python-sdk伟恶,使用之后卻發(fā)現(xiàn)不支持Python3儒溉,于是決定移植到Python3上面。

在移植的過(guò)程中须妻,發(fā)現(xiàn)原來(lái)的代碼在import不能正確導(dǎo)入同一package下的module,在網(wǎng)上搜尋方案無(wú)果泛领,怒翻譯Python官方的PEP 0328

感謝chickenjohn桑在翻譯過(guò)程中給予的幫助荒吏。也希望各位多給予指導(dǎo)。

目錄

摘要
Timeline
使用括號(hào)的原因
使用絕對(duì)導(dǎo)入的原因
使用相對(duì)導(dǎo)入的原因
Guido的選擇
相對(duì)導(dǎo)入與__name__屬性
相對(duì)導(dǎo)入與sys.modules中的間接尋址入口
參考資料
版權(quán)所有

摘要

import聲明存在兩個(gè)問(wèn)題:

  • 過(guò)長(zhǎng)的import聲明很難寫渊鞋,可能為了符合Python編碼規(guī)范出現(xiàn)很多換行绰更。
  • 存在很多包的情況下,import操作可能存在語(yǔ)義含糊不清的情況锡宋;例如儡湾,在一個(gè)包中,import foo操作可能代表導(dǎo)入了包內(nèi)的foo模塊员辩,也可能代表導(dǎo)入了包外的foo模塊盒粮。(更準(zhǔn)確的說(shuō),一個(gè)本地的模塊或包可能直接切斷了與外部(即sys.path)的聯(lián)系奠滑。)

對(duì)于第一個(gè)問(wèn)題丹皱,我們建議用括號(hào)將要導(dǎo)入的名稱括起來(lái),以滿足Python的換行標(biāo)準(zhǔn)宋税。對(duì)于第二個(gè)問(wèn)題摊崭,我們建議所有的import默認(rèn)以絕對(duì)路徑的方式聲明,并用特殊語(yǔ)法(即開頭的.)表示相對(duì)路徑杰赛。

Timeline

在Python 2.5中呢簸,加入以下語(yǔ)句可以應(yīng)用新的絕對(duì)路徑標(biāo)準(zhǔn):

  __future__ import absolute_import

如此就能優(yōu)雅的使用相對(duì)路徑導(dǎo)入了。在Python 2.6中乏屯,任何出現(xiàn)包內(nèi)導(dǎo)入的import操作都會(huì)引起DeprecationWarning(這對(duì)于沒(méi)有使用相對(duì)導(dǎo)入語(yǔ)法的from <> import操作同樣適用)根时。

使用括號(hào)的原因

現(xiàn)在,如果要從一個(gè)模塊或包中導(dǎo)入很多名稱時(shí)辰晕,你不得不從如下不夠優(yōu)雅的方式中做出選擇:

  • 利用反斜杠分隔開:

    from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \\\\
    LEFT, DISABLED, NORMAL, RIDGE, END
    
  • 將一次import操作分為多次import

    from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
    from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END
    

( 不討論import *的情況 ;-)
作為替代蛤迎,應(yīng)使用Python標(biāo)準(zhǔn)的分組機(jī)制進(jìn)行import操作:

  from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, 
  LEFT, DISABLED, NORMAL, RIDGE, END)

這個(gè)建議從提出開始就被BDFL審批。

Python 2.4版本開始引入這種括號(hào)的支持

使用絕對(duì)導(dǎo)入的原因

在Python 2.4和更早的版本中含友,

  import foo

這個(gè)語(yǔ)句可能指代一個(gè)庫(kù)中的頂層模塊替裆,也可能指代另一個(gè)本地包中的模塊校辩。作為Python標(biāo)準(zhǔn)庫(kù)的擴(kuò)展,越來(lái)越多的包內(nèi)模塊無(wú)意中與Python標(biāo)準(zhǔn)庫(kù)的同名模塊產(chǎn)生了沖突辆童。這個(gè)問(wèn)題導(dǎo)致了很多時(shí)候無(wú)法確定它導(dǎo)入了哪一個(gè)模塊宜咒,從而產(chǎn)生歧義。為了消除這個(gè)歧義把鉴,我們建議此種方式導(dǎo)入的foo必須是在sys.path中可以找到的模塊或包故黑。此方式的導(dǎo)入稱為絕對(duì)導(dǎo)入。

Python-dev社區(qū)默認(rèn)選用絕對(duì)導(dǎo)入的原因是這種方式在實(shí)際中更常用纸镊,而且能提供所有使用相對(duì)導(dǎo)入時(shí)可提供的功能倍阐,盡管這可能導(dǎo)致一系列麻煩:例如修改頂層包名稱以及修改包目錄結(jié)構(gòu)。

因?yàn)檫@可能導(dǎo)致語(yǔ)義上的變動(dòng)逗威,在Python 2.5和2.6中,絕對(duì)導(dǎo)入不是必須遵守的岔冀,加入以下語(yǔ)句可以應(yīng)用絕對(duì)引用標(biāo)準(zhǔn):

  from __future__ import absolute_import

這個(gè)建議從提出開始就被BDFL審批凯旭。

使用相對(duì)導(dǎo)入的原因

與絕對(duì)導(dǎo)入相對(duì)的,是否允許相對(duì)導(dǎo)入的問(wèn)題也出現(xiàn)了使套。示例如下罐呼,這些示例的重點(diǎn)在于如何規(guī)整大包的結(jié)構(gòu)而不必在大包的子包中做改動(dòng)。除此之外侦高,不使用相對(duì)導(dǎo)入很難單獨(dú)導(dǎo)入包內(nèi)的一個(gè)模塊嫉柴。

Guido認(rèn)可相對(duì)導(dǎo)入這種導(dǎo)入方式,但是相對(duì)導(dǎo)入在語(yǔ)法上可能產(chǎn)生很多歧義奉呛。有一個(gè)不成文的約定就是相對(duì)導(dǎo)入需要列出導(dǎo)入的的具體名稱(就是說(shuō)计螺,形如import foo單獨(dú)的導(dǎo)入被認(rèn)為是絕對(duì)導(dǎo)入)。

不同的相對(duì)導(dǎo)入方式如下:

  • Guido的導(dǎo)入方式

    from .foo import bar
    

以及

  from ...foo import bar

這兩種形式有很多不同的解釋方式瞧壮。 一種解釋方式是一個(gè).表示文件結(jié)構(gòu)中的一個(gè)層級(jí)登馒。這樣的話有很多人抱怨,數(shù).的個(gè)數(shù)很麻煩咆槽,顯然不夠優(yōu)雅陈轿。另外一個(gè)選擇是只允許一個(gè)文件層次之間的相對(duì)導(dǎo)入。這樣又會(huì)造成很多功能上的喪失秦忿,還有很多人抱怨在這種表示下會(huì)忘記.麦射。最終的方案是聲明一種相對(duì)導(dǎo)入尋找包與模塊的算法,而這又違反了“The Zen of Python”中的"Explicit is better than implicit"(外顯勝于內(nèi)隱)灯谣。(這個(gè)被提議的算法主要思想是“自下而上潜秋,直至觸頂”)

有些人提出使用其他標(biāo)點(diǎn)符號(hào)作為分隔符,比如“-”或者"^"酬屉。

有些人提出使用"*"

  from *.foo import bar
  • 還有一個(gè)選擇是從很多包結(jié)構(gòu)中導(dǎo)入:
    from pkg.pkg import

    from parent.parent import

很多人(包括Guido)認(rèn)為這種方式看起來(lái)很丑半等,但是這種方式非常明確而且一目了然揍愁。 總之,更多人喜歡以__pkg__作為更短的選項(xiàng)杀饵。

  • 有人提出只允許同一文件層級(jí)之間的引用莽囤。 換句話說(shuō),用相對(duì)導(dǎo)入無(wú)法導(dǎo)入更高層級(jí)的模塊切距,只能以如下方式導(dǎo)入:
    from .spam import eggs
    或者
    import .spam.eggs

  • 有的人喜歡索引的父目錄表示方式
    from -2.spam import eggs
    這種方式下朽缎,從當(dāng)前目錄導(dǎo)入只需要如下方式:
    from .spam import eggs

  • 最后,當(dāng)要導(dǎo)入的包處于比較深的文件結(jié)構(gòu)時(shí)谜悟,一些人不愿意從import的寫法改為from ... import话肖。他們建議重寫import的語(yǔ)法:
    from MODULE import NAMES as RENAME searching HOW
    或者
    import NAMES as RENAME from MODULE searching HOW
    [from NAMES] [in WHERE] import ...
    然而,這在Python 2.5中很可能不能實(shí)現(xiàn)(改動(dòng)過(guò)大)葡幸,允許相對(duì)導(dǎo)入非常關(guān)鍵最筒,所以()除此之外,這個(gè)被建議的語(yǔ)法有很多問(wèn)題:

  • 準(zhǔn)確的語(yǔ)法是什么蔚叨?(什么條件下應(yīng)用)
  • searching字句應(yīng)對(duì)應(yīng)什么床蜘?也就是說(shuō),應(yīng)該采用一下哪種方式:
    import foo as bar searching XXX, spam as ham searching XXX
    或者
    import foo as bar, spam as ham searching XXX

Guido的選擇

Guido已經(jīng)宣布[1]相對(duì)導(dǎo)入要在導(dǎo)入路徑前面加一個(gè).表示當(dāng)前的包蔑水,兩個(gè)或者更多的.表示在當(dāng)前包的父包中進(jìn)行相對(duì)導(dǎo)入操作邢锯,一個(gè).表示一個(gè)層級(jí)。以下是一個(gè)包的樣例:

  package/
     __init__.py
     subpackage1/
         __init__.py
         moduleX.py
         moduleY.py
      subpackage2/
          __init__.py
          moduleZ.py
      moduleA.py

假設(shè)所在的文件是moduleX.pysubpackage1/__init__.py, 新語(yǔ)法的正確用法如下:

  from .moduleY import spam
  from .moduleY import spam as ham
  from . import moduleY
  from ..subpackage1 import moduleY
  from ..subpackage2.moduleZ import eggs
  from ..moduleA import foo
  from ...package import bar
  from ...sys import path

注意搀别,雖然最后一個(gè)例子中的用法是合法的丹擎,但是不推薦這樣做。(Guido用瘋狂(insane)這個(gè)詞來(lái)形容這種做法)

相對(duì)導(dǎo)入必須使用形如from <> import的方式; 形如import <>的均視為絕對(duì)導(dǎo)入歇父。當(dāng)然蒂培,絕對(duì)導(dǎo)入也可以通過(guò)省略.的方式進(jìn)行from <> import操作。 禁止使用import .foo的原因是:在

  import XXX.YYY.ZZZ

操作后庶骄,

  XXX.YYY.ZZZ

可以在表達(dá)式中使用毁渗,而

 .module

不能在表達(dá)式中使用。

相對(duì)導(dǎo)入與__name__屬性

相對(duì)導(dǎo)入使用一個(gè)模塊的__name__屬性確定模塊在包層次結(jié)構(gòu)中的位置单刁。如果模塊的名字不包含任何包的信息(比如它被設(shè)置為__main__)灸异,相對(duì)導(dǎo)入就會(huì)以處理最頂層模塊一樣處理,無(wú)視這個(gè)模塊的實(shí)際位置羔飞。

相對(duì)導(dǎo)入與sys.modules中的間接尋址入口

當(dāng)包的概念被引出時(shí)肺樟,在sys.modules中間接尋址入口的概念應(yīng)運(yùn)而生[2]。當(dāng)一個(gè)sys.module中一個(gè)包中的模塊的入口的值是None的時(shí)候逻淌,它表示當(dāng)前模塊確實(shí)表示頂層么伯。例如,'Sound.Effects.string'sys.modules的值可能是None卡儒。這意味著導(dǎo)入對(duì)應(yīng)'Sound.Effects.string'的操作就是導(dǎo)入string模塊田柔。

這又引出了一個(gè)當(dāng)絕對(duì)導(dǎo)入對(duì)應(yīng)相對(duì)導(dǎo)入情況下的的優(yōu)化方式俐巴。但是在PEP對(duì)于絕對(duì)導(dǎo)入和相對(duì)導(dǎo)入有著明確界定的情況下,這種優(yōu)化方式就不再需要了硬爆。當(dāng)絕對(duì)導(dǎo)入或相對(duì)導(dǎo)入成為了唯一可用的導(dǎo)入方式時(shí)欣舵,sys.modules中的間接尋址入口不再支持。

參考資料

了解更多相關(guān)背景可以參考以下主題:

版權(quán)所有

這個(gè)文檔已被放置在公共域名缀磕。
來(lái)源:https://hg.python.org/peps/file/tip/pep-0328.txt

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缘圈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子袜蚕,更是在濱河造成了極大的恐慌糟把,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牲剃,死亡現(xiàn)場(chǎng)離奇詭異遣疯,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)颠黎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門另锋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人狭归,你說(shuō)我怎么就攤上這事∥呐校” “怎么了过椎?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)戏仓。 經(jīng)常有香客問(wèn)我疚宇,道長(zhǎng),這世上最難降的妖魔是什么赏殃? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任敷待,我火速辦了婚禮,結(jié)果婚禮上仁热,老公的妹妹穿的比我還像新娘榜揖。我一直安慰自己,他們只是感情好抗蠢,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布举哟。 她就那樣靜靜地躺著,像睡著了一般迅矛。 火紅的嫁衣襯著肌膚如雪妨猩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天秽褒,我揣著相機(jī)與錄音壶硅,去河邊找鬼威兜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛庐椒,可吹牛的內(nèi)容都是我干的椒舵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼扼睬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼逮栅!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起窗宇,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤措伐,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后军俊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侥加,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年粪躬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了担败。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡镰官,死狀恐怖提前,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泳唠,我是刑警寧澤狈网,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站笨腥,受9級(jí)特大地震影響拓哺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脖母,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一士鸥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谆级,春花似錦烤礁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至建峭,卻和暖如春玻侥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亿蒸。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工凑兰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掌桩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓姑食,卻偏偏與公主長(zhǎng)得像波岛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子音半,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理则拷,服務(wù)發(fā)現(xiàn),斷路器曹鸠,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • Python是一種對(duì)代碼風(fēng)格很重視的語(yǔ)言煌茬,從縮進(jìn)就能看出這一點(diǎn),Python強(qiáng)調(diào)易于理解彻桃。最近在負(fù)責(zé)代碼重構(gòu)的工作...
    知曰閱讀 10,785評(píng)論 1 85
  • 前言 Python的創(chuàng)始人為Guido van Rossum坛善。1989年圣誕節(jié)期間,在阿姆斯特丹邻眷,Guido為了打...
    依依玖玥閱讀 3,563評(píng)論 6 37
  • 1.傾盡天下——河圖 血染江山的畫肆饶,怎敵你眉間 一點(diǎn)朱砂改衩。覆了天下也罷,始終不過(guò) 一場(chǎng)繁華驯镊。碧血染就桃花燎字,只想再見(jiàn)...
    愛(ài)上一匹野馬閱讀 959評(píng)論 0 0
  • hazel默認(rèn)不處理子文件夾,要處理子文件夾阿宅,你必須分開建立兩個(gè)規(guī)則。 要處理子文件夾必須先建立一個(gè)這樣的規(guī)則 然...
    鴨梨山大哎閱讀 838評(píng)論 0 0