Pythonの識別子における Unicode文字

| コメント(0) | トラックバック(0)

プログラミング言語Pythonで,変数名のような識別子に使える文字の種類は何だったかなとウェブを検索したところ,出てきたページに,UnicodeのカテゴリMn (結合文字)が使えないという意味の説明がありました。おや,そんなことあるかな,とちょっと調べてみました。

カテゴリMnとは

Unicodeは符号位置ごとに文字のカテゴリを属性として与えています。例えばラテンアルファベット大文字AであればUppercase Letter (Lu),ドル記号($)であればCurrency Symbol (Sc)などです。漢字や平仮名のように大文字小文字の区分のない文字はOther Letter (Lo)に分類されます。個々の符号位置のカテゴリはUnicode Consortiumが配布しているUnicodeData.txtに記されています。

これらのカテゴリのうち,結合文字はNonspacing Mark (Mn), Spacing Mark (Mc), Enclosing Mark (Me)になります。日本での使用で見るものはMnが多いでしょう。フランス語に用いるCOMBINING ACUTE ACCENT (U+0301)や,片仮名の濁点COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK (U+3099)などがこれです。

Unicodeに言語仕様から対応しているプログラミング言語では識別子に英語以外の様々な言語の文字に対応していることがあります。最初からUnicode前提に設計されたJavaでは変数名に「あ」「字」のような平仮名や漢字を使うこともできます。Pythonのバージョン3系も同様です。

ここで,もしカテゴリMnつまり結合文字が使えないと,多言語対応に支障が生じることになります。上記のフランス語のアクセント記号などは基底文字のアルファベットと合成済みの符号位置,例えばé (U+00E9)が用意されているので結合文字がなくても表現できますが,全てにおいてそうとは限りません。初期のUnicodeとは異なり,今日では結合文字を使って表現可能な文字は独立した符号位置に収録されない傾向にあります。例えば比較的最近Unicodeに追加された文字に,日本語でかつて使われていた変体仮名がありますが,濁点つきの文字は結合文字を使って表現できるため収録されていません。

手っ取り早く試してみる

Pythonのインタプリタを使うと手っ取り早く試すことができます。pythonコマンドを実行して,

>>> ㇷ゚ = 1
>>> ㇷ゚
1

よし,大丈夫ですね。ここで,最初の行は変数「ㇷ゚」(プの小書きです) に整数1を代入しています。ここでエラーにならなければOK。次の行は変数の値を確認しています。「ㇷ゚」はブラウザでは1文字に見えていると思いますが,実際には2つの符号位置の並び,つまり基底文字「ㇷ」と結合半濁点とで実現されています。「ㇷ」のカテゴリがLo, それに続く半濁点がMnです。つまり,この変数がエラーにならないということは,変数名としてカテゴリMnの結合文字が使えたことになります。

小書きの「ㇷ゚」を入力するのには,Macではアイヌ語入力方式にして「p [リターン]」と打鍵すればよし。Windows 10では「ぷ」から変換キーを何度か叩けば出てくるはずです。コマンドプロンプトでは半濁点が1文字分の幅をとってしまうようですがプログラムの動作には支障ありません。

言語仕様

きちんと確認するにはPythonの言語仕様にあたる必要があります。変数名のような識別子については,2.3. Identifiers and keywordsに記載されています。

ここを見ると,識別子の2文字目以降にはカテゴリMnの文字が使えることがわかります。識別子は先頭に数字が使えない言語が多く,先頭とそれ以降とで扱いが異なるのが普通ですが,特に結合文字は2文字目以降でないと意味がありません。

私が最初に見たウェブの記事は,識別子先頭と後続との違いを考慮していなかったようです。

ちなみにPython2では識別子はASCIIの英数字とアンダースコアに限定されていたようです。

どういうときに使われるか

さて,変数名にアルファベット以外が使えるといっても,通常のプログラムでは用いないことがほとんどでしょう。ではどういうときに使われるか。

フレームワークなどで,入力ファイルから自動生成するような場合が一例に挙げられます。Pythonのポピュラーなライブラリpandasでは,CSVファイルを簡単に読み込んで様々な処理ができますが,その中で以下のようにデータ項目にアクセスできます。

>>> import pandas as pd
>>> df = pd.read_csv('sample.csv')
>>> df
   ID      名前        生年月日
0   1    Taro  1980-10-11
1   2  Hanako  1981-11-12
>>> for row in df.itertuples():
...   print(row.名前)
...   print(row.生年月日)
... 
Taro
1980-10-11
Hanako
1981-11-12

最後のforループで,「row.生年月日」のように,named tupleの機能によって読み込んだCSVファイルの列名からデータにアクセスしています。

余談

Unicodeにいろいろな文字があるので風変わりな見た目のコード,例えば楔形文字を使って 𒐪 = 8 のようなコードを書くこともできますが,あとで困るかもしれないのでほどほどに。

トラックバック(0)

トラックバックURL: http://yanok.net/yanok/mt-tb.cgi/657

コメントする

最近のブログ記事

停電対策として自宅にUPSを導入した話
私は写真撮影が趣味で,撮影した写真は自宅…
Javaと Pythonの識別子の仕様を比較する
前の記事で,Pythonの識別子のUni…
Pythonの識別子における Unicode文字
プログラミング言語Pythonで,変数名…
アニメ「シュタインズ・ゲート」における文字コード技術入門
以前,何年も前ですが,アニメ「シュタイン…
仮名合字・合略仮名の文字コード
合字とは 合字というものがあります。複数…

広告