LoginSignup
5
6

More than 5 years have passed since last update.

コードを綺麗に

Last updated at Posted at 2018-12-03

研究で、機械学習をやり始めて早半年、綺麗なコードを書けるようになっときたいなぁということで調べました。

キャメルケース

これは複合語をひと綴りとして、要素語の最初を大文字で書き表す記法である。

名称 表記例 備考
アッパーキャメルケース GetInputReader 先頭を大文字で
ローワーキャメルケース getInputReader 先頭を小文字で

システムハンガリアン記法

pythonでは型宣言がないため、長いコードを書く場合、変数がどんな型だったか迷うケースがあります。この記法を使用することでミスを減らすことができる。
ただ、

文字 意味 使用例
b または f 論理型 bDirtyFlag
ch 文字型 chSeparator
by バイト型 (符号なし1バイト整数) byGrayLevel
n または i 整数型 (int, integer) nPower
l 長整数 (long) lDate
u 符号なし整数 uiCount
w ワード型 (WORD) wLanguageCode
dw ダブルワード型 (DWORD) dwSize
fp または f 単精度浮動小数点型 fpPrice
db または d 倍精度浮動小数点型 dPi
p または lp ポインタ型 lpDirectSound
s 文字列型 sPlayerName
sz ゼロ終端文字列型 szFileName
fn 関数ポインタ型 fnCallback
h ハンドル型 hThread
hwnd または h ウィンドウハンドル型 (Windowsのみ) hMainWindow
g_ グローバル変数 g_iErrorCode
c_ 定数 (const) c_nBufferSize
s_ 静的変数 (static) s_pLookupTable
m_ クラスのメンバー変数 m_nLength
C クラス CHoge
tag 構造体タグ tagRECT

命名規則

関数名、変数名はスネークケース、クラス名はキャメルケース、プライベートは"_"始まり。

対象 ルール 付録
パッケージ 全小文字 なるべく短くアンダーバー非推奨 tqdm, requests ...  
モジュール 全小文字 なるべく短くアンダーバー非推奨 sys, os,...  
クラス 最初大文字 + 大文字区切り MyFavoriteClass  
例外 最初大文字 + 大文字区切り MyFuckingException  
型変数 最初大文字 + 大文字区切り MyFavoriteType  
メソッド 全小文字 + アンダーバー区切り my_favorite_method 内部メソッドはアンダーで開始
関数 全小文字 + アンダーバー区切り my_favorite_funcion  
変数 全小文字 + アンダーバー区切り my_favorite_instance 内部変数はアンダーで開始
定数 全大文字 + アンダーバー区切り MY_FAVORITE_CONST  

アンダースコア

アンダースコア_を使用したメソッドやメンバ変数には二種類存在する。

  • シングルアンダースコア_ : 定義される関数は参照はできるが、基本的に外部から参照しないという慣習規則
  • ダブルアンダースコア__ : プライベートっぽくする文法規則

基本的には、プライベートなフィールドを記述する場合、シングルアンダースコア_で充分である。
ダブルアンダースコア__にすると一見外部から参照できないように見えるが、実際は_ClassName__paramNameといった名前でアクセスができてしまう。これをネームマングリング(名前修飾)と言う。そもそもこの機能は、親クラスと子クラスで名前が衝突しないように作られた機能であって、プライベートなメンバ変数を提供するための機能ではないことに注意である。

sampleclass.py
class SampleClass:
    def __init__(self):
        self.publicParam = 'publicParam'
        self._singlePrivateParam = '_singlePrivateParam'
        self.__doublePrivateParam = '__doublePrivateParam'

s = SampleClass()
print(s.publicParam)                      # publicParam
print(s._singlePrivateParam)              # _singlePrivateParam
#print(s.__doublePrivateParam)            # AttributeError: 'SampleClass' object has no attribute '__doublePrivateParam'
print(s._SampleClass__doublePrivateParam) # __doublePrivateParam

docstring

Pythonでは関数やクラスなどの定義の直後に文字列を記述するとdocstringとして扱われる。
docstringはprint(関数名.__doc__)help(関数名)で出力できる。docstringの書き方は、reST,Epytext,Google,Numpydoc等があるが、広く使われているNumpydocでの記述例を以下に提示する。

クラスコメント

class
class Fruit(object):
    """
    果物の各属性値やヘルパー関数を保持する。

    Attributes
    ----------
    fruit_id : int
        対象の果物のマスタID。
    fruit_name : str
        果物名。
    price_dict : dict
        キーに地域のID、値に該当する地域での値段を保持した辞書。
    """
print(Fruit.__doc__)
#help(Fruit)

#果物の各属性値やヘルパー関数を保持する。
#
#Attributes
#----------
#fruit_id : int
##対象の果物のマスタID。
#fruit_name : str
##果物名。
#price_dict : dict
##キーに地域のID、値に該当する地域での値段を保持した辞書。

メソッドコメント

method
def get_fruit_price(fruit_id):
    """
    果物の値段を取得する。

    Parameters
    ----------
    fruit_id : int or None, default None
        対象の果物のマスタID。
    fruit_id_arr : array-like
        対象の果物のマスタIDを格納した配列。
    location_id : int
        対象地域のマスタID。

    Returns
    -------
    fruit_price : int
        対象の果物の値段。
    fruit_price_list : list of int
        果物の値段を格納したリスト。
    consumption_tax : int
        消費税値。

    See Also
    --------
    get_fruit_id_list : DBに保存されている果物のマスタIDのリストを取得する。

    Notes
    -----
    スイカは野菜側として扱われる。

    Raises
    ------
    ValueError
        Raises ValueError if `a` contains NaN (Not a Number) or Inf (Infinity).

    Examples
    --------
    >>> a = np.array([[1,4],[3,1]])
    >>> np.sort(a)                # sort along the last axis
    array([[1, 4],
           [1, 3]])
    >>> np.sort(a, axis=None)     # sort the flattened array
    array([1, 1, 3, 4])
    >>> np.sort(a, axis=0)        # sort along the first axis
    array([[1, 1],
           [3, 4]])
    """
    # ...関数内容省略。
    return fruit_price

mainブロック

mainとして実行されたときのみ処理が実行されるようにする方法である。
例えば、このsample.pyをimportなどした時はmainが実行されない利点がある。

sample.py
if __name__ == "__main__":
    main()

参考文献

Qiita 変数名の命名規則/**ケースの使い分け
Wikipedia ハンガリアン記法
Qiita それっぽいPythonコードのテンプレート
Qiita Python命名規則一覧
Qiita 【備忘録】Pythonにおけるアンダースコア"_"の役割について
Qiita [Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル)
コメントに関する規約
sphinx入門 その2 コード内のdocstringの記述
stackoverflow 標準的なPythonのdocstring形式は何ですか?
NumPy および Google スタイルの docstring をドキュメントに取り込む
標準的なPythonのdocstring形式は何ですか?
[Pythonコーディング規約]PEP8を読み解く

5
6
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6