Pythonでは、privateな変数やメソッドの名前には
_(アンダースコア)を慣習的につけるが本当はアクセスできる。
__(アンダースコア×2)の場合は本当にアクセスできなくなる(特殊な指定方法を使えばアクセス可能)
という話を聞きました。
質問1. でもこれってどう使い分けるのでしょうか。
そもそもprivateな変数やメソッドでも慣習的にアンダースコアを使ってない場合も多いですよね。
質問2. アンダースコア、普段使ってますか?使う利点はありますか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
Pythonの標準コーディングスタイルを定めるPEP 8にてガイドラインが説明されています。以下、日本語訳バージョンから部分引用します:
_single_leading_underscore
: “内部でだけ使う” ことを示します。たとえばfrom M import *
は、アンダースコアで始まる名前のオブジェクトをインポートしません。
__double_leading_underscore
: クラスの属性に名前を付けるときに、名前のマングリング機構を呼び出します (クラスFoobar
の__boo
という名前は_FooBar__boo
になります。以下も参照してください)
公開されていないメソッドやインスタンス変数にだけ、アンダースコアを先頭に付けてください。
サブクラスと名前が衝突した場合は、Pythonのマングリング機構を呼び出すためにアンダースコアを先頭に二つ付けてください。
- 公開されている(public)属性の先頭にはアンダースコアを付けない
- もしあなたが公開している属性の名前が予約語と衝突する場合は、属性の名前の直後にアンダースコアを追加します。省略語を使ったり、スペルミスをするよりはマシです。
- サブクラス化して使うクラスがあるとします。サブクラスで使って欲しくない属性があった場合、その名前の最後ではなく、先頭にアンダースコアを二つ付けることを検討してみましょう。これによって Python のマングリングアルゴリズムが呼び出され、その属性にはクラス名が付加されます。これはサブクラスにうっかり同名の属性が入ってしまうことによる属性の衝突を避けるのに役立ちます。
投稿2016/07/19 02:59
総合スコア6191
0
PythonでフレームワークをDjangoを使っています。views.pyでクラスを使いhtmlとのやり取りをするのですが、その時mixinを使いある特定の処理を付け加える時に、内部処理にprivateなメソッドを使っています。
例えば
python
1# views.py 2# フォームクラスに特定の処理が出来るmixinを2つ付け加えている。 3class ImportMemberIDFormView(SetMemberIDMixin, GetCsvDataMixin, FormView): 4 template_name = 'csvs/import_all_userdates.html' 5 form_class = ImportAllUserDatesForm 6 success_url = reverse_lazy('userdates:home') 7 8 def get_context_data(self, *args, **kwargs): 9 context = super(ImportMemberIDFormView, self).get_context_data( 10 *args, **kwargs) 11 context['title'] = 'クラブメンバーIDのインポート' 12 return context 13 14 def form_valid(self, form): 15 # CSVのファイルからデータ抽出 16 data_list = self.get_csvdate() 17 # データのバリデーション 18#特定のmixinのメソッド 19 csv_data_list = self.get_memberid_cleardates(data_list=data_list) 20 if messages.get_level(self.request) < 1000: 21 # データのsave 22 self.save_memberid(csv_data_list=csv_data_list) 23 messages.success(self.request, 'CSVからのクラブメンバーIDを同期しました。') 24 messages.set_level(self.request, None) 25 return super(ImportMemberIDFormView, self).form_valid(form)
python
1class SetMemberIDMixin(object): 2 def get_memberid_cleardates(self, *args, **kwargs): 3 data_list = kwargs['data_list'] 4 clean_data_list = [] 5 for i, values in enumerate(data_list): 6 if i is not 0: 7 for val_len in range(0, len(values)): 8 # memberIDはCSVの3番目 9 if val_len is 2: 10 # 配列を先頭から挿入 11 value = data_list[i][val_len] 12 # ここで内部処理を使用 13 value = self.__core_set_memberid(value=value, row=i) 14 clean_data_list.append(value) 15 # 重複をチェック 16 ....中略 17#内部でのみ(views.pyから参照されたくないメソッド) 18 def __core_set_memberid(self, *args, **kwargs): 19 value = kwargs['value'] 20 row = kwargs['row'] + 1 21 22 if len(value) is not 11: 23 message = '%s番目の %s が11桁ではありません。' % (str(row), str(value)) 24 messages.add_message(self.request, messages.ERROR, message) 25 messages.set_level(self.request, 1000) 26 27 try: 28 value = int(value) 29 except: 30 message = '%s番目の %s が数字ではありません。' % (str(row), str(value)) 31 messages.add_message(self.request, messages.ERROR, message) 32 messages.set_level(self.request, 1000) 33 value = 0 34 ...中略
投稿2016/07/16 03:51
総合スコア40
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/16 04:00
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/07/20 05:25