web-dev-qa-db-ja.com

関数名の前後にアンダースコア「__」が付いている関数があるのはなぜですか?

これはよく起こるようで、これがPython言語の要件なのか、それとも単なる慣習の問題なのか疑問に思いましたか。

また、誰かがどの機能にアンダースコアを付ける傾向があるのか​​、そしてその理由を説明することができますか、そしてその理由は何ですか(例えば__init__)。

366
Chuck Testa

Python PEP 8 - Pythonコードのスタイルガイド :より

記述:命名スタイル

先頭または末尾のアンダースコアを使用した次の特殊形式が認識されます(これらは一般に大文字と小文字の区別を組み合わせることができます)。

  • _single_leading_underscore:弱い "内部使用"インジケータ例えば。 from M import *は、名前がアンダースコアで始まるオブジェクトをインポートしません。

  • single_trailing_underscore_:Pythonキーワードとの衝突を避けるために規約で使われています。

    Tkinter.Toplevel(master, class_='ClassName')

  • __double_leading_underscore:クラス属性に名前を付けると、名前マングリングが呼び出されます(クラスFooBar内では、__boo_FooBar__booになります。下記参照)。

  • __double_leading_and_trailing_underscore__:ユーザー制御の名前空間に存在する「魔法の」オブジェクトまたは属性。例えば。 __init____import__または__file__。そのような名前を発明しないでください。文書化されている場合にのみ使用してください。

二重の先頭と末尾のアンダースコアを持つ名前は、本質的にPython自身のために予約されていることに注意してください。

465
Michael Burr

他の回答者は、 "特別な"または "魔法の"メソッドの命名規則として二重の先頭と末尾のアンダースコアを説明するのに正しいです。

これらのメソッドを直接呼び出すことはできますが([10, 20].__len__()など)、アンダースコアがあることは、これらのメソッドが間接的に呼び出されることを意図していることを示すヒントです(例えばlen([10, 20]))。ほとんどのpython演算子は、関連する「マジック」メソッドを持っています(例えば、a[x]a.__getitem__(x)を呼び出す通常の方法です)。

50

二重下線で囲まれた名前はPythonにとって「特別な」ものです。それらは Pythonランゲージリファレンス、セクション3、 "データモデル" にリストされています。

親クラスと子クラスの名前を区別する必要がある場合は、実際には_メソッド名を使用します。このように親子クラスを作成するためのコードをいくつか読みました。例として、私はこのコードを提供することができます:

class ThreadableMixin:
   def start_worker(self):
       threading.Thread(target=self.worker).start()

   def worker(self):
      try:
        self._worker()
    except tornado.web.HTTPError, e:
        self.set_status(e.status_code)
    except:
        logging.error("_worker problem", exc_info=True)
        self.set_status(500)
    tornado.ioloop.IOLoop.instance().add_callback(self.async_callback(self.results))

...

_workerメソッドを持つ子

class Handler(tornado.web.RequestHandler, ThreadableMixin):
   def _worker(self):
      self.res = self.render_string("template.html",
        title = _("Title"),
        data = self.application.db.query("select ... where object_id=%s", self.object_id)
    )

...

5
Omadbek Onorov

この規則は、_init__、 len などの特殊な変数またはメソッド(いわゆる「マジックメソッド」)に使用されます。これらのメソッドは特別な構文上の特徴を提供したり特別なことをします。

例えば、 file はPythonファイルの場所を示し、 eq はa == b式が実行されたときに実行されます。

もちろんユーザはカスタムの特別な方法を作ることができます、それは非常にまれなケースですが、しばしばいくつかの組み込みの特別な方法を修正するかもしれません。 (たとえば、クラスのインスタンスが作成されたときに最初に実行される init でクラスを初期化する必要があります。)

   class A:
      def __init__(self, a): # use special method '__init__' for initializing
        self.a = a
      def __custom__(self): # custom special method. you might almost do not use it
        pass
0
Shagun Pruthi

二重下線(Name Mangling)/ Pythonドキュメントから

__spam形式の識別子(先頭の2つのアンダースコア、末尾の1つ以下のアンダースコア)は、テキストで_classname__spamに置き換えられます。classnameは、先頭のアンダースコアが削除された現在のクラス名です。このマングリングは、識別子の構文上の位置に関係なく行われるため、クラスプライベートインスタンスとクラス変数、メソッド、グローバルに格納された変数、さらにはインスタンスに格納された変数の定義にも使用できます。他のクラスのインスタンス上でこのクラスにプライベートです。

名前マングリングは、派生クラスによって定義されたインスタンス変数を心配したり、クラス外のコードによってインスタンス変数を無視したりせずに、クラスに「プライベート」インスタンス変数とメソッドを簡単に定義できるようにすることを目的としています。マングリングルールは主に事故を避けるために設計されていることに注意してください。それでも、決心した魂がプライベートと見なされる変数にアクセスまたは変更することは可能です。

0
Arefe