pythonのアンダーバーこれなんやねん

はじめに

初心者丸出しの投稿ですみませんが同じように悩む初心者の方がいると信じて書きます。

ちょいちょい出てくるアンダーバー

人のコードとか参考書とか読んでて,出てきませんか?
このアンダーバーなんやねん!_みたいなアンダーバー

H,W,_ = img.shape 

とか,まず

__main__

ってなんでアンダーバーいるねん。みたいな。
今回はそういうお話です。

今回も悩んで調べてる間に神記事見つけたのでそれをもとに肉付けしたり噛み砕いたりしてまとめようと思います。
悩み解決してくれた神記事はこちら

「Pythonic色々」 Pythonのアンダースコア( _ )を使いこなそう!

return値を無視するための_

H,W,_ = img.shape 

まさに最初に例に挙げたこれがそれにあたります。これがそれ...
これは.shapeの三番目のreturn値を無視するよーのアンダーバー
引用元が過不足説明してくださっているので引用
曰く

Pythonはライブラリが沢山あって、関数をインポートして使う事が多いです。そういう時、もし関数からのreturn値が複数あって使わない部分があったらアンダースコアを使ってreturn値のメモリの占用をしないまま廃棄ができます

これで無駄なメモリを使わずにプログラムが組めるというわけなんですね。これが一番使いそう。

関数名についてる_

これ,場所によって4種類あるんだそうで.しかもPEP8コーディング規約で定義されてるとのこと。こんな定義があることも知らなかった。
https://www.python.org/dev/peps/pep-0008/

PEP8>Naming Conventionに諸々詳しく書かれています。
それでは以下に4つまとめていきます

_function(x): 関数前に1つ

def _single_leading_underscore(x):
    return n
#weak "internal use" indicator. E.g. from M import *
#does not import objects whose names start with an underscore.

こう書くと,別のところからfrom func import*で呼ばれることがなくなるけど,classx._func()というようにclass内の関数としてはアンダーバー付きの関数を呼べるんだそうです。基本的に外部からの参照を受け付けない,ってものにはアンダーバーを1つつけるというのがpythonの習わしのようです。
これも読み込み対策ですかね。

function(x)_: 関数後に1つ

def list_(x):
    return n
#used by convention to avoid conflicts with Python keyword

listやclassなどpythonの予約語をどーしても関数名に使いたい時には,後ろに1つ_つけてつかいわけろ,ということみたいです。

__function(x): クラス名の前に2つ

def __double_leading_underscore:
     return n
#when naming a class attribute, invokes name mangling 
#(inside class FooBar, __boo becomes _FooBar__boo; see below).

クラス内の関数の前にアンダーバー2つをつけると名前のマングリングを呼び出します。マングリングとは,名前修飾,の意で,要するに内部的に普通のものとして取り扱いませんよってことみたいです。
上の例に書いてるとおり,class FooBar内の変数__booは, FooBar.__booでは呼び出せず,_FooBar__booとなるとしないと呼び出せないとのこと。
これも外部からのアクセスを受け付けませんよ対策の1つと言えるのではないかと思います。

function(x): 関数前後に2つずつ

def __double_leading_and_trailing_underscore__: 
    return n
# "magic" objects or attributes that live in user-controlled 
# namespaces. E.g. __init__, __import__ or __file__. Never invent 
# such names; only use them as documented.``

class内の関数の前後に2つずつアンダーバーをつけるとMagic Method(特殊メソッド)になります。特殊メソッドってなんやねーんって話ですが,オブジェクトの振る舞いを変更したり,クラスの性質にあった動きをさせたい時に使うものなんだそうです。
たとえば__init__は,渡された引数を使って.クラス定義で新しく作られたオブジェクトを初期化するものです。magic methodいっぱいありますよね。リスト載せてくださっていますがいっぱいです
http://www.ops.dti.ne.jp/ironpython.beginner/method.html

数字を読みやすくする_

>>> 1000000
Out: 1000000
>>> 1_000_000
Out: 1000000

これはもろ参考からいただいてきたものですが,python3.6以降では3桁ごとのカンマのかわりにアンダーバーを数値に打ち込んでもちゃんとした数値としてにんしきしてくれる,ということみたいです。
桁の大きな数値入れ込みたい時は便利ですね。

インタプリタで最後に表示された値を示す_

>>> 1
Out: 1
>>> _ * 3
Out: 3
>>> _ * 10
Out: 30

これは知らなかったのですが,pythonインタプリタを使っている時,アンダーバーで前に表示した数値を取得できるみたいです。

じゃあif__name__ == '__main__' って何

これは美しくまとめてくださっているサイトを見つけました
Pythonのif __name__ == '__main__'の意味と使い方

「該当のファイルがコマンドラインからスクリプトとして実行された場合にのみ以降の処理を実行する」ということになるみたいです。
つまりどこかから呼び出されたときには動かないということ

他人のコード読んでると,これがメイン関数ですよ〜ってのを示すために書かれてたりするような気がします。

おわりに

美しいコードが書きたいもんですね。

その他参考

[Pythonチートシート]特殊メソッド編
マークダウン記法でアンダースコアを入れる方法

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
コメント
この記事にコメントはありません。
あなたもコメントしてみませんか :)
すでにアカウントを持っている方は
ユーザーは見つかりませんでした