#!/usr/bin/env python3 from typing import Union, Text, ByteString import logging import sys from argparse import ArgumentParser import pypinyin style_map = { 'NORMAL': pypinyin.Style.NORMAL, 'zhao': pypinyin.Style.NORMAL, 'TONE': pypinyin.Style.TONE, 'zh4ao': pypinyin.Style.TONE, 'TONE2': pypinyin.Style.TONE2, 'zha4o': pypinyin.Style.TONE2, 'TONE3': pypinyin.Style.TONE3, 'zhao4': pypinyin.Style.TONE3, 'INITIALS': pypinyin.Style.INITIALS, 'zh': pypinyin.Style.INITIALS, 'FIRST_LETTER': pypinyin.Style.FIRST_LETTER, 'z': pypinyin.Style.FIRST_LETTER, 'FINALS': pypinyin.Style.FINALS, 'ao': pypinyin.Style.FINALS, 'FINALS_TONE': pypinyin.Style.FINALS_TONE, '4ao': pypinyin.Style.FINALS_TONE, 'FINALS_TONE2': pypinyin.Style.FINALS_TONE2, 'a4o': pypinyin.Style.FINALS_TONE2, 'FINALS_TONE3': pypinyin.Style.FINALS_TONE3, 'ao4': pypinyin.Style.FINALS_TONE3, 'BOPOMOFO': pypinyin.Style.BOPOMOFO, 'BOPOMOFO_FIRST': pypinyin.Style.BOPOMOFO_FIRST, 'CYRILLIC': pypinyin.Style.CYRILLIC, 'CYRILLIC_FIRST': pypinyin.Style.CYRILLIC_FIRST, } func_map = { 'pinyin': pypinyin.pinyin, 'slug': pypinyin.slug, } default_style = 'zh4ao' class NullWriter(): """数据流黑洞,类似 linux/unix 下 /dev/null 的效果。""" def write(self, string: Union[Text, ByteString]) -> None: pass def get_parser() -> ArgumentParser: parser = ArgumentParser(description='convert chinese to pinyin.') parser.add_argument( '-V', '--version', action='version', version='{0} {1}'.format(pypinyin.__title__, pypinyin.__version__)) # 要执行的函数名称 parser.add_argument( '-f', '--func', help='function name (default: "pinyin")', choices=['pinyin', 'slug'], default='pinyin') # 拼音风格 parser.add_argument( '-s', '--style', help='pinyin style (default: "{0}")'.format(default_style), choices=style_map.keys(), default=default_style) parser.add_argument( '-p', '--separator', help='slug separator (default: "-")', default='-') parser.add_argument( '-e', '--errors', help=('how to handle none-pinyin string' ' (default: "default")'), choices=['default', 'ignore', 'replace'], default='default') # 输出多音字 parser.add_argument( '-m', '--heteronym', help='enable heteronym', action='store_true') # 要查询的汉字 parser.add_argument('hans', help='chinese string') return parser def main(): # 禁用除 CRITICAL 外的日志消息 logging.disable(logging.CRITICAL) # read hans from stdin if not sys.stdin.isatty(): pipe_data = sys.stdin.read().strip() else: pipe_data = '' args = sys.argv[1:] if pipe_data: args.append(pipe_data) # 获取命令行选项和参数 parser = get_parser() options = parser.parse_args(args) hans = options.hans func = getattr(pypinyin, options.func) style = style_map[options.style] heteronym = options.heteronym separator = options.separator errors = options.errors func_kwargs = { 'pinyin': { 'heteronym': heteronym, 'errors': errors }, 'slug': { 'heteronym': heteronym, 'separator': separator, 'errors': errors }, } kwargs = func_kwargs[func.__name__] # 重设标准输出流和标准错误流 # 不输出任何字符,防止污染命令行命令的输出结果 # 其实主要是为了干掉 jieba 内的 print 语句 ;) sys.stdout = sys.stderr = NullWriter() result = func(hans, style=style, **kwargs) # 恢复默认 sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ if not result: print('') elif result and isinstance(result, (list, tuple)): if isinstance(result[0], (list, tuple)): print(' '.join([','.join(s) for s in result])) else: print(result) else: print(result) if __name__ == '__main__': main()