Python 脚本编程及国际化 (2)

自动重启程序时依靠 subprocess.Popen 对象实现的,启动的时候实例化一个 Popen 对象,停止程序时调用它的 kill() 方法;重启就是先 kill 再重新实例化。这个过程用 NewProcess 类进行封装:

import sys from watchdog.observers import Observer import subprocess class NewProcess(object): def __init__(self, config: dict): self.process = None self.config = config self.command = self.config["cmd_args"][:] self.command[0:0] = self.config["cmd"] self.args = ' '.join(self.command)

然后还需要用到 watchdog.observers.Observer,用来监听目录,并且通知处理器进行处理:

class NewProcess(object): def start_watch(self): observer = Observer() observer.schedule(MyFileSystemEventHander(self._restart, self.config), path=self.config["mon_dir"], recursive=self.config["recursive"] ) observer.start() logger.info('Watching directory: {}'.format(self.config["mon_dir"])) self._start() try: while True: time.sleep(0.5) except KeyboardInterrupt: observer.stop() observer.join()

脚本就完成了。可以在命令行中尝试一下,输入 bf_monitor -c echo -a test 可以看到类似的输出:

Python 脚本编程及国际化

它还有些缺陷,不能在 -a 后面添加的参数里带有 - 前缀:bf_monitor -c echo -a -test 是不允许的:

Python 脚本编程及国际化

为了解决这个问题,只有在 -c 后面将这些命令用引号包裹起来,bf_monitor -c "python -V" :

Python 脚本编程及国际化

关于 watchdog 的详细使用或者 API,请参阅其 官方文档.

P3 python 国际化 i18n

到目前为止,我已经用 Python 做了两个脚本:bf_gitrepo 和 bf_monitor,并且我给他们都加上了命令行帮助信息,但是它们的帮助信息都是英文,我们要把这些信息翻译成中文。翻译工作主要依靠 Python 的 gettext 模块和第三方的 pybabel 模块。

事实上,国际化只要尝试一遍流程之后就很简单了,我第一次使用 pybabel 时,大部分时间都是在提取可翻译文本上,之后做 monitor.py 脚本的翻译时就轻车熟路,完成的很快,只在翻译上花了点时间。

在 brifuture-facilities 中,我将 gettext 模块简单的封装了一下,程序会在脚本的同级目录下寻找 locale 文件夹中的 .mo 文件,然后替换脚本中的文本:

LANGUAGE_DIR = (Path(__file__).parent / "locale").resolve() import gettext def initGetText(domain="myfacilities") -> gettext.gettext: gettext.bindtextdomain(domain, LANGUAGE_DIR) gettext.textdomain(domain) gettext.find(domain, "locale", languages=["zh_CN", "en_US"]) return gettext.gettext

一般会将 gettext.gettext 以其他的名称导入到 Python 程序中,如 from gettext import gettext as _,由于之前我习惯用 Qt 翻译方法 tr,所以我将 gettext.gettext 用别名 tr 代替。在程序中要替换文本的位置用 tr 方法包裹起来:

parser.add_argument("-d", "--directory", help=tr("The directory to monitor, . by default."))

然后我们需要配置 babel,要读取的只有 python 文件(如果你要读取其他文件,可以看看 [文档]():

# file: babel.cfg # Extraction from Python source files [python: **.py] keywrods = tr 文本查找

接下来使用 pybabel 程序进行文本查找,我们只用查找 monitor.py 文件:

# pybabel extract -F ./babel.cfg -o ./bffacilities/locale/{}.pot -k tr ./bffacilities/{}.py pybabel extract -F ./babel.cfg -o ./bffacilities/locale/monitor.pot -k tr ./bffacilities/monitor.py

尽管前面的配置文件中指定了关键字为 tr,但我在使用中发现调用 extract 子命令时最好还是加上选项 -k tr,保证能够提取出文本。

查看 bffacilities/locale 目录下,应该有 monitor.pot 文件,里面有很多的 msgid、msgstr。这个文件就保存了所有要翻译的文本。当程序中的文本更新后,重新调用上面的命令再次提取文本即可。

文本翻译

然后我们要对提取出来的文本进行翻译,如果是初次翻译要使用 init 子命令,但若是更新翻译就不是用 init 子命令而是用 update 子命令了:

# pybabel init -i ./bffacilities/locale/{}.pot -d ./bffacilities/locale/ -l zh_CN -D {} pybabel init -i ./bffacilities/locale/monitor.pot -d ./bffacilities/locale/ -l zh_CN -D monitor # pybabel update -i ./bffacilities/locale/{}.pot -d ./bffacilities/locale/ -l zh_CN -D {} pybabel update -i ./bffacilities/locale/monitor.pot -d ./bffacilities/locale/ -l zh_CN -D monitor

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxsjp.html