使用Python3中的gettext模組翻譯Python源碼以支援多語言_python

來源:互聯網
上載者:User

你寫了一個Python 3程式,還想要它適用於其他語言。你能複製全部程式碼程式庫,然後刻意地檢查每個.py檔案,替換掉所有找到的文本字串。但這意味著你有兩份你代碼的獨立副本,每當你要做出個改動或修複個bug,你的工作量會加倍。而且如果你想要程式還適用於其他語言,就更糟了。

幸運的是,Python給了一個解決辦法,就是用gettext模組。
一個Hack解法

你應該把你自己的解決辦法統一改變。例如,你可以把你程式中的每個字串替換為一個函數調用(函數名簡單些,比如像_()一樣),這會返回被翻譯為該正確語言的字串。舉個例子,如果你的程式原本是:
 

print('Hello world!')

……你可以將它改為:
 

print(_('Hello world!'))

……函數_()會返回'Hello world!'的翻譯,它基於程式設定有的語言。比如,如果這個語言設定之前被存在一個叫LANGUAGE的全域變數中,函數_()看起來像這樣:
 

def _(s):  spanishStrings = {'Hello world!': 'Hola Mundo!'}  frenchStrings = {'Hello world!': 'Bonjour le monde!'}  germanStrings = {'Hello world!': 'Hallo Welt!'}   if LANGUAGE == 'English':    return s  if LANGUAGE == 'Spanish':    return spanishStrings[s]  if LANGUAGE == 'French':    return frenchStrings[s]  if LANGUAGE == 'German':    return germanStrings[s]

這可以,但是你這是在重複造輪子。Python的gettext模組可以做更多。gettext是一系列工具,檔案格式在20世紀90年代被發明出來,來規範軟體國際化(也叫I18N)。gettext是個作為對於所有程式設計語言的系統化的設計,但是我們會在本篇文章中只專註於Python。
程式例子

設想你有個想要翻譯的用Python3寫的簡單“猜數字”遊戲。程式的原始碼在這裡。有四步來使這個程式國際化:

    調整這個.py檔案的原始碼,這樣使字串輸入進一個名為_()的函數。
    用和Python一起安裝的pygettext.py文本,從原始碼建立一個”pot”檔案。
    用這個免費的跨平台Poedit軟體,從pot檔案建立.po和.mo檔案。
    再次調整你的.py檔案原始碼匯入gettext模組的代碼,設定語言。

第一步:添加 _() 函數

首先,檢查你程式中的所有需要被翻譯和用_()的調用來替代的字串。針對Python使用的gettext系統用_()作為得到翻譯了的字串的通用名,因為它是個短名。

注意:用格式型字串而不是串連型字串會是你的程式翻譯起來更簡單。例如,用串連型字串你的程式會像這樣:
 

print('Good job, ' + myName + '! You guessed my number in ' + guessesTaken + ' guesses!')print(_('Good job, ') + myName + _('! You guessed my number in ') + guessesTaken + _(' guesses!'))

This results in three separate strings that need to be translated, as opposed to the single string needed in the string formatting approach:
這會導致三個獨立的字串都需要翻譯,然而相反的是在格式型的字串中,只需翻譯一個字串:

print('Good job, %s! You guessed my number in %s guesses!' % (myName, guessesTaken))
print(_('Good job, %s! You guessed my number in %s guesses!') % (myName, guessesTaken))

當你改完“猜數字”原始碼後,它會像這樣。你並不能運行它,因為_()函數還沒定義。這個變化只是讓pygettext.py文本可以找到所有需要翻譯的字串。
第二步:用pygettext.py提取字串

在你Python安裝(Windows上的C:Python34Toolsi18n)中的Tools/i18n就是pygettext.py文本。對於可譯字串普通 gettext unix 命令解析 C/C++ 源碼並且 xgettext unix 命令可以解析其他語言,而pygettext.py則知道怎樣去解析Python源碼。它會找到所有字串併產生個”pot”檔案。

在Windows上我已經運行了這個文本像這樣:
 

C:>py -3.4 C:Python34Toolsi18npygettext.py -d guess guess.py

這建立了一個pot檔案,叫guess.pot。這隻是個普通純文字檔案,它列出來了全部的在源碼中尋找_()的調用的要翻譯的字串。你可以在這兒看guess.pot檔案.
第三步:用Poedit翻譯字串

你可以用文字編輯器填寫翻譯但是免費的Poedit軟體會更容易從這兒下載http://poedit.net. 選擇 > New from POT/PO file… 然後選擇你的guess.po檔案。

Poedit會問你想要翻譯成什麼語言。我們舉例用西班牙語:

填寫翻譯吧。(我用 http://translate.google.com,所以對於真的使用西班牙語的人會感覺有點奇怪。)

現在儲存檔案在它的gettext形式的檔案夾裡。儲存會建立.po檔案(一個人類可讀的文字檔不同於原始.pot檔案,除了是有西語翻譯的)和一個.mo檔案(一個gettext會讀取的機器可讀版本。這些檔案會存在一個特定的檔案夾內,為的是讓gettext能夠找到他們。他們看起來像這樣(比如西語檔案中的”es”和德語檔案中”de”):
 

./guess.py./guess.pot./locale/es/LC_MESSAGES/guess.mo./locale/es/LC_MESSAGES/guess.po./locale/de/LC_MESSAGES/guess.mo./locale/de/LC_MESSAGES/guess.po

這些兩種性質的語言像西語中的”es”和德語中的 ”de” 被稱作ISO 639-1 codes 是語言的標準縮寫。你不一定要用他們,但是遵循標準是有道理的。
第四步:給你程式加上gettext代碼

現在你有包含翻譯的.mo檔案,調整你的Python代碼去用它。在你的程式中加上下面的:
 

import gettextes = gettext.translation('guess', localedir='locale', languages=['es'])es.install()

第一個 'guess' 是”定義域”,這其實是意味著guess.mo檔案名稱中“猜”的部分。 localedir是你建立的locale檔案夾的目錄位址。這會是相對或絕對的路徑。'es'描述在locale檔案夾下面的檔案。LC_MESSAGES檔案夾是個標準名

install()方法會導致調用_()返回翻譯為西語的字串。如果你想回到原始的英語只需要分配一個lambda函數值給_,這會返回當時輸入的字串:
 

import gettextes = gettext.translation('guess', localedir='locale', languages=['es'])print(_('Hello! What is your name?')) # prints Spanish _ = lambda s: s

你可以檢查準備翻譯的”Guess the Number”源碼。如果你想要運行此程式,下載並解壓這個壓縮檔和它的locale檔案夾和.mo安裝檔案。
延伸閱讀

我怎樣都稱不上是 I18N or gettext的專家,如果我的教程講解不夠好,請一定要留言。大多數情況下,你的軟體運行時不會轉換語言,而是會去讀LANGUAGE,LC_ALL,LC_MESSAGES,和LANG這些環境變數中的一個來確定電腦的工作地點。我會邊學習邊更新本教程的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.