最近碰到了一個問題,專案中很多檔案都是接手過來的中文命名的一些素材,結果在部署的時候檔名全都亂碼了,導致專案無法正常執行。

後來請教了一位大佬怎麼解決檔名亂碼的問題,他說這個需要正面解決嗎?不需要,把檔名全部改掉,檔名永遠不要用中文,永遠不要。

我想他這麼說的話,一定也是憑經驗得出來的。

這裡也友情提示大家,專案裡面檔案永遠不要用中文,永遠不要!

好,那不用中文用啥?平時來看,一般我們都會用英文來命名,一般也不會出現中文,比如 resource, controller, result, view, spider 等等,所以絕大多數情況下,是不會出現什麼問題的。但是也有個別的情況,比如一些素材、資原始檔可能的中文命名的,那麼這時候該咋辦呢?

首先像,因為是中文資原始檔,我們要改成非中文命名的,無非兩種,一種是英文,一種是拼音。

如果改英文,當然可以翻譯、我們想翻譯的話,逐個人工翻譯成本太高,機器翻譯的話,翻譯完可能有些文不對題了,而且我們自己也不知道一些奇怪的資源英語應該叫什麼,所以到時候真的找起來都找不到了。

所以第二種解決方案,那就是拼音了。中文轉拼音,很自然,而且一個字就對應一串拼音,而且也非常容易從拼音看懂是什麼意思,所以這確實是一個不錯的方案。

那麼問題就來了,怎樣把一批中文檔案轉拼音命名呢?下面就讓我們來了解 Python 的一個庫 PyPinyin 吧!

概述

Python 中提供了漢字轉拼音的庫,名字叫做 PyPinyin,可以用於漢字注音、排序、檢索等等場合,是基於 hotto/pinyin 這個庫開發的,一些站點連結如下:

它有這麼幾個特性:

根據片語智慧匹配最正確的拼音。

支援多音字。

簡單的繁體支援, 注音支援。

支援多種不同拼音/注音風格。

是不是等不及了呢?那就讓我們來了解一下它的用法吧!

安裝

首先就是這個庫的安裝了,通過 pip 安裝即可:

pip3 install pypinyin

安裝完成之後匯入一下這個庫,如果不報錯,那就說明安裝成功了。

>>> import pypinyin

好,接下來我們看下它的具體功能。

基本拼音

首先我們進行一下基本的拼音轉換,方法非常簡單,直接呼叫 pinyin 方法即可:

from pypinyin import pinyin

print(pinyin('中心'))

執行結果:

[['zhōng'], ['xīn']]

可以看到結果會是一個二維的列表,每個元素都另外成了一個列表,其中包含了每個字的讀音。

那麼如果這個詞是多音字咋辦呢?比如 “朝陽”,它有兩個讀音,我們拿來試下:

from pypinyin import pinyin

print(pinyin('朝陽'))

執行結果:

[['zhāo'], ['yáng']]

好吧,它只給出來了一個讀音,但是如果我們想要另外一種讀音咋辦呢?

其實很簡單,只需新增 heteronym 引數並設定為 True 就好了,我們試下:

from pypinyin import pinyin

print(pinyin('朝陽', heteronym=True))

執行結果:

[['zhāo', 'cháo'], ['yáng']]

OK 了,這下子就顯示出來了兩個讀音了,而且我們也明白了結果為什麼是一個二維列表,因為裡面的一維的結果可能是多個,比如多音字的情況就是這樣。

但這個多少解析起來有點麻煩,很多情況下我們是不需要管多音字的,我們只是用它來轉換一下名字而已,而處理上面的二維陣列又比較麻煩。

所以有沒有一個方法直接給我們一個一維列表呢?有!

我們可以使用 lazy_pinyin 這個方法來生成,嘗試一下:

from pypinyin import pinyin

print(pinyin('聰明的小兔子'))

執行結果:

['cong', 'ming', 'de', 'xiao', 'tu', 'zi']

這時候觀察到得到的是一個列表,並且不再包含音調了。

這裡我們就有一個疑問了,為啥 pinyin 方法返回的結果預設是帶音調的,而 lazy_pinyin 是不帶的,這裡面就涉及到一個風格轉換的問題了。

風格轉換

我們可以對結果進行一些風格轉換,比如不帶聲調風格、標準聲調風格、聲調在拼音之後、聲調在韻母之後、注音風格等等,比如我們想要聲調放在拼音後面,可以這麼來實現:

from pypinyin import lazy_pinyin, Style

style = Style.TONE3

print(lazy_pinyin('聰明的小兔子', style=style))

執行結果:

['cong1', 'ming2', 'de', 'xiao3', 'tu4', 'zi']

可以看到執行結果每個拼音後面就多了一個聲調,這就是其中的一個風格,叫做 TONE3,其實還有很多風格,下面是我從原始碼裡面找出來的定義:

#: 普通風格,不帶聲調。如: 中國 -> ``zhong guo``

NORMAL = 0

#: 標準聲調風格,拼音聲調在韻母第一個字母上(預設風格)。如: 中國 -> ``zhōng guó``

TONE = 1

#: 聲調風格2,即拼音聲調在各個韻母之後,用數字 [1-4] 進行表示。如: 中國 -> ``zho1ng guo2``

TONE2 = 2

#: 聲調風格3,即拼音聲調在各個拼音之後,用數字 [1-4] 進行表示。如: 中國 -> ``zhong1 guo2``

TONE3 = 8

#: 聲母風格,只返回各個拼音的聲母部分(注:有的拼音沒有聲母,詳見 `#27`_)。如: 中國 -> ``zh g``

INITIALS = 3

#: 首字母風格,只返回拼音的首字母部分。如: 中國 -> ``z g``

FIRST_LETTER = 4

#: 韻母風格,只返回各個拼音的韻母部分,不帶聲調。如: 中國 -> ``ong uo``

FINALS = 5

#: 標準韻母風格,帶聲調,聲調在韻母第一個字母上。如:中國 -> ``ōng uó``

FINALS_TONE = 6

#: 韻母風格2,帶聲調,聲調在各個韻母之後,用數字 [1-4] 進行表示。如: 中國 -> ``o1ng uo2``

FINALS_TONE2 = 7

#: 韻母風格3,帶聲調,聲調在各個拼音之後,用數字 [1-4] 進行表示。如: 中國 -> ``ong1 uo2``

FINALS_TONE3 = 9

#: 注音風格,帶聲調,陰平(第一聲)不標。如: 中國 -> ``ㄓㄨㄥ ㄍㄨㄛˊ``

BOPOMOFO = 10

#: 注音風格,僅首字母。如: 中國 -> ``ㄓ ㄍ``

BOPOMOFO_FIRST = 11

#: 漢語拼音與俄語字母對照風格,聲調在各個拼音之後,用數字 [1-4] 進行表示。如: 中國 -> ``чжун1 го2``

CYRILLIC = 12

#: 漢語拼音與俄語字母對照風格,僅首字母。如: 中國 -> ``ч г``

CYRILLIC_FIRST = 13

有了這些,我們就可以輕鬆地實現風格轉換了。

好,再回到原來的問題,為什麼 pinyin 的方法預設帶聲調,而 lazy_pinyin 方法不帶聲調,答案就是:它們二者使用的預設風格不同,我們看下它的函式定義就知道了:

pinyin 方法的定義如下:

def pinyin(hans, style=Style.TONE, heteronym=False, errors='default', strict=True)

lazy_pinyin 方法的定義如下:

def lazy_pinyin(hans, style=Style.NORMAL, errors='default', strict=True)

這下懂了吧,因為 pinyin 方法預設使用了 TONE 的風格,而 lazy_pinyin 方法預設使用了 NORMAL 的風格,所以就導致二者返回風格不同了。

好了,有了這兩個函式的定義,我們再來研究下其他的引數,比如定義裡面的 errors 和 strict 引數又怎麼用呢?

錯誤處理

在這裡我們先做一個測試,比如我們傳入無法轉拼音的字,比如:

from pypinyin import lazy_pinyin

print(lazy_pinyin('你好☆☆,我是xxx'))

其中包含了星號兩個,還有標點一個,另外還包含了一個 xxx 英文字元,結果會是什麼呢?

['ni', 'hao', '☆☆,', 'wo', 'shi', 'xxx']

可以看到結果中星號和英文字元都作為一個整體並原模原樣返回了。

那麼這種特殊字元可以單獨進行處理嗎?當然可以,這裡就用到剛才提到的 errors 引數了。

errors 引數是有幾種模式的:

u

下面是 errors 這個引數的原始碼實現邏輯:

def _handle_nopinyin_char(chars, errors='default'):

"""處理沒有拼音的字元"""

if callable_check(errors):

return errors(chars)

if errors == 'default':

return chars

elif errors == 'ignore':

return None

elif errors == 'replace':

if len(chars) > 1:

return ''.join(text_type('%x' % ord(x)) for x in chars)

else:

return text_type('%x' % ord(chars))

當處理沒有拼音的字元的時候,errors 的不同引數會有不同的處理結果,更詳細的邏輯可以翻看原始碼。

好了,下面我們來嘗試一下,比如我們想將不能轉拼音的字元去掉,則可以這麼設定:

from pypinyin import lazy_pinyin

print(lazy_pinyin('你好☆☆,我是xxx', errors='ignore'))

執行結果:

['ni', 'hao', 'wo', 'shi']

如果我們想要自定義處理,比如把 ☆

轉化為 ※

,則可以這麼設定:

print(lazy_pinyin('你好☆☆,我是xxx', errors=lambda item: ''.join(['※' if c == '☆' else c for c in item])))

執行結果:

['ni', 'hao', '※※,', 'wo', 'shi', 'xxx']

如上便是一些相關異常處理的操作,我們可以隨心所欲地處理自己想處理的字元了。

嚴格模式

最後再看下 strict 模式,這個引數用於控制處理聲母和韻母時是否嚴格遵循 《漢語拼音方案》

標準。

下面的一些說明來源於官方文件:

當 strict 引數為 True 時根據 《漢語拼音方案》

的如下規則處理聲母、在韻母相關風格下還原正確的韻母:

21 個聲母: b p m f d t n l g k h j q x zh ch sh r z c s

( y, w 不是聲母

)

i行的韻母,前面沒有聲母的時候,寫成yi(衣),ya(呀),ye(耶),yao(腰),you(憂),yan(煙), yin(因),yang(央),ying(英),yong(雍)。( y 不是聲母

)

u行的韻母,前面沒有聲母的時候,寫成wu(烏),wa(蛙),wo(窩),wai(歪),wei(威),wan(彎), wen(溫),wang(汪),weng(翁)。( w 不是聲母

)

ü行的韻母,前面沒有聲母的時候,寫成yu(迂),yue(約),yuan(冤),yun(暈);ü上兩點省略。 ( 韻母相關風格下還原正確的韻母 ü

)

ü行的韻跟聲母j,q,x拼的時候,寫成ju(居),qu(區),xu(虛),ü上兩點也省略; 但是跟聲母n,l拼的時候,仍然寫成nü(女),lü(呂)。( 韻母相關風格下還原正確的韻母 ü

)

iou,uei,uen前面加聲母的時候,寫成iu,ui,un。例如niu(牛),gui(歸),lun(論)。 ( 韻母相關風格下還原正確的韻母 iou,uei,uen

)

當 strict 為 False 時就是不遵守上面的規則來處理聲母和韻母, 比如: y

, w

會被當做聲母,yu(迂) 的韻母就是一般認為的 u

等。

具體差異可以檢視原始碼中 tests/test_standard.py

中的對比結果測試用例。

自定義拼音

如果對庫返回的結果不滿意,我們還可以自定義自己的拼音庫,這裡用到的方法就有 load_single_dict 和 load_phrases_dict 方法了。

比如剛才我們看到 “朝陽” 兩個字的發音預設返回的是 zhao yang,我們想預設返回 chao yang,那可以這麼做:

from pypinyin import lazy_pinyin, load_phrases_dict

print(lazy_pinyin('朝陽'))

personalized_dict = {

'朝陽': [['cháo'], ['yáng']]

}

load_phrases_dict(personalized_dict)

print(lazy_pinyin('朝陽'))

這裡我們自定義了一個詞典,然後使用 load_phrases_dict 方法設定了一下就可以了。

執行結果:

['zhao', 'yang']

['chao', 'yang']

這樣就可以完成自定義的設定了。

在一些專案裡面我們可以自定義很多拼音庫,然後載入就可以了。

另外我們還可以註冊樣式實現自定義,比如將某個拼音前面加上 Emoji 表情,樣例:

from pypinyin.style import register

from pypinyin import lazy_pinyin

@register('kiss')

def kiss(pinyin, **kwargs):

if pinyin == 'me':

return f':kissing_heart:{pinyin}'

return pinyin

print(lazy_pinyin('麼麼噠', style='kiss'))

執行結果:

[':kissing_heart:me', ':kissing_heart:me', 'dá']

這裡我們呼叫 register 方法註冊了一個樣式 style,然後轉換的時候指定即可,通過觀察執行結果我們可以發現,這樣我們就可以將 me 字的拼音前面加上 :kissing_heart: 這個 Emoji 表情了。

python拼音四线格书写格式_Python 中拼音庫 PyPinyin 的用法相关推荐

  1. python拼音四线格书写格式_Python pypinyin库,实现文字转拼音

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 这年头什么样子的需求都会出现,下面这张图就是很好的体现了.这就是说为啥要你学学P ...

  2. Python基础_第3章_Python中的循环结构

    Python基础_第3章_Python中的循环结构 文章目录 Python基础_第3章_Python中的循环结构 Python中的循环结构 一.回顾分支练习题 1.判断是否为一个合法三角形 2.求世界 ...

  3. Python基础_第5章_Python中的数据序列

    Python基础_第5章_Python中的数据序列 文章目录 Python基础_第5章_Python中的数据序列 Python中的数据序列 一.字典--Python中的==查询==神器 1.为什么需要 ...

  4. python书写格式_python并的写法

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 最近倒腾python,希望能坚持下去吧发现了个叫codecademy的网站,还不 ...

  5. python语言流程控制语句的格式_Python流程控制语句的深入讲解

    1.程序结构 计算机在解决问题时,分别是顺序执行所有语句.选择执行部分语句.循环执行部分语句,分别是:顺序结构.选择结构.循环结构.如下图: 2.选择语句 2.1最简单的if语句 Python使用保留 ...

  6. python json模块有什么用_Python中json模块与jsonpath模块的区别是什么

    Python中json模块与jsonpath模块的区别是什么 发布时间:2021-02-02 11:15:52 来源:亿速云 阅读:94 作者:小新 这篇文章主要介绍了Python中json模块与js ...

  7. python中time函数用法_python中time tzset()函数实例用法

    在时间的设置方面,为了能够跟系统时间有更好的区分,我们有时会借用一些函数方法来实现.就拿tzset()来说是设置时间的一种方法,其内在的变量依靠TZ的控制,如果没有设置TZ则以系统时间为准.接下来我们 ...

  8. python怎么宏定义符号变量_python中定义宏

    广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 什么是宏? 宏类似python中的函数,可以传参数进去,但不能有返回值! 在实际 ...

  9. python defaultdict函数_Python中defaultdict与lambda表达式用法

    这篇文章主要介绍了Python中defaultdict与lambda表达式用法,在这里分享给大家,需要的朋友可以参考下 本文实例讲述了Python中defaultdict与lambda表达式用法.分享 ...

  10. python中mat函数_Python中flatten( )函数及函数用法详解

    flatten()函数用法 flatten是numpy.ndarray.flatten的一个函数,即返回一个一维数组. flatten只能适用于numpy对象,即array或者mat,普通的list列 ...

最新文章

  1. iOS NSArray数组过滤
  2. [机器学习]机器学习笔记整理12-线性回归概念理解
  3. DL之SqueezeNet:SqueezeNet算法的架构详解
  4. python封装sql脚本 github_Github 大牛封装 Python 代码,实现自动发送邮件只需三行代码...
  5. 数字证书格式详细说明【转】
  6. tomcat如何查找请求资源的?
  7. java中自定义输入数字格式_Java 创建并使用自定义数字格式、35;###、####.#####和语言环境...
  8. Python注释风格--Google风格
  9. java性能测试jmh
  10. 7-5 输出字符串中出现的字符 (20 分)
  11. Java SE Technologies at a Glance
  12. bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线(二分+SPFA)
  13. swift 笔记 (十三) —— 继承
  14. Web浏览器测试,怎么提取测试点 - web测试方法总结
  15. In-Place Scene Labelling and Understanding with Implicit Scene Representation
  16. linux express 安装,linux下的node+express安装教程
  17. MyBatis多对多关系映射
  18. duilib设置透明窗口_使用duilib开发半透明异形窗体程序(补充)
  19. 雨林木风(Ylmf OS)操作系统 点评
  20. Android 前置摄像头预览与编码

热门文章

  1. linux中21个中级命令
  2. 阿里成立“平头哥”半导体公司,明年推神经网络芯片
  3. win安装android系统服务,拯救你的旧电脑:整个win+Android的双系统
  4. 集合易支付源码完美版
  5. c语言测试单句代码运行时间,c语言测试代码的运行时间
  6. Python关键字keyword
  7. Codevs 1253 超级市场
  8. MySQL第一节课总结
  9. 信息系统项目管理师学习笔记13-项目合同管理
  10. 简单易懂的Kubernetes(K8S)之Pod资源管理与harbor创建