web-dev-qa-db-ja.com

Pythonクラスはオブジェクトを継承

クラス宣言がobjectから継承する理由はありますか?

これを実行するコードがいくつか見つかりましたが、その正当な理由が見つかりません。

class MyClass(object):
    # class code follows...
959
tjvr

クラス宣言がobjectname__から継承する理由はありますか?

tl; dr:Python 3では、Python 2と3の間の互換性は別として、理由なし。Python2では多くの理由).


Python 2.xの物語:

Python 2.x(2.2以降)には、基本クラスとしてのobjectname__の有無に応じて、2つのクラスのスタイルがあります。

  1. "クラシック"スタイル classes:objectname__を基本クラスとして持ちません。

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. "new" style classes:直接または間接的に(たとえば 組み込み型から継承 ))、objectname__を基本クラスとして持っています。

    >>> class NewSpam(object):           # directly inherit from object
    ...    pass
    >>> NewSpam.__bases__
    (<type 'object'>,)
    >>> class IntSpam(int):              # indirectly inherit from object...
    ...    pass
    >>> IntSpam.__bases__
    (<type 'int'>,) 
    >>> IntSpam.__bases__[0].__bases__   # ... because int inherits from object  
    (<type 'object'>,)
    

間違いなく、クラスを書くとき、あなたは常に新しいスタイルのクラスに行きたいです。そのようにすることの利点はそれらのいくつかを挙げるとたくさんあります:

objectname__から継承しない場合は、これらを忘れてください。 "新しい"スタイルクラスの他の特典と一緒に以前の箇条書きの点のより徹底的な説明は見つけることができます ここ

新しいスタイルのクラスの欠点の1つは、クラス自体がより多くのメモリを必要とすることです。あなたが多くのクラスオブジェクトを作成しているのでなければ、しかし、私はこれが問題になるとは思わないし、それは肯定的な海の中で否定的な沈み込みである。


Python 3.xの物語:

Python 3では、物事は単純化されています。新しいスタイルのクラスだけが存在し(単純にクラスと呼ばれる)、objectname__を追加する唯一の違いは、さらに8文字を入力する必要があることです。この:

class ClassicSpam:
    pass

これと完全に同等です(それらの名前を除いて:-)。

class NewSpam(object):
     pass

そしてこれに:

class Spam():
    pass

すべての__bases__objectname__があります。

>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]

それで、あなたは何をすべきですか?

Python 2の場合: 常にobjectname__から明示的に継承する。特典を受けましょう。

Python 3の場合: Pythonに依存しないようにする、つまりPython 2とPython 3の両方で機能する必要があるコードを作成している場合はobjectname__を継承Pythonがあなたのために舞台裏でそれを挿入して以来の違い。

471

Python 3.x:
class MyClass(object): =新しいスタイルのクラス
class MyClass: =新しいスタイルのクラス(暗黙的にオブジェクトから継承)

Python 2.x:
class MyClass(object): =新しいスタイルのクラス
class MyClass: = 旧スタイルクラス

説明:

Python 3.xで基本クラスを定義するときは、定義からオブジェクトを削除することができます。しかし、これは問題を突き止めるのが非常に難しい問題への扉を開くことができます…

PythonはPython 2.2で新しいスタイルのクラスを導入しました、そして今では古いスタイルのクラスは本当にかなり古くなっています。古いスタイルのクラスの議論は 2.xのドキュメントに埋め込まれています 、そして3.xのドキュメントには存在しません。

問題は、 Python 2.xの古いスタイルのクラスの構文は、Python 3.xの新しいスタイルのクラスの代替構文と同じである です。 Python 2.xはまだ非常に広く使用されており(例えばGAE、Web2Py)、3.xスタイルのクラス定義を無意識のうちに2.xコードに取り込むコード(またはコーダー)は、いずれも深刻な古くなった基本オブジェクトになってしまいます。そして、古いスタイルのクラスは誰の手にもわからないので、何が彼らに当たるのかわからないでしょう。

それで、長い道のりを詳しく書いて、2.xの開発者たちを涙から救ってください。

508
Yarin

はい、これは「新しいスタイル」のオブジェクトです。これはpython2.2で導入された機能です。

新しいスタイルオブジェクトは、古典的なオブジェクトとは異なるオブジェクトモデルを持っています。例えば、super()@property、記述子など、古いスタイルのオブジェクトでは正しく動作しないものがあります。新しいスタイルクラスが何であるかの良い説明については この記事 を見てください。

違いについての説明はSOリンク: Pythonの古いスタイルと新しいスタイルのクラスの違いは何ですか?

393
Jerub

Pythonを使いこなす の歴史

Pythonの元々のクラス表現は、多くの重大な点で壊れていました。この過ちが認識される頃には、それはもう遅すぎた、そして彼らはそれを支持しなければならなかった。この問題を解決するために、彼らは "古いクラス"が機能し続けるように "新しいクラス"スタイルを必要としましたが、あなたは新しくより正しいバージョンを使うことができます。

彼らはあなたがクラスを作るためにあなたが継承する「クラス」であるために、彼らは小文字のWordの「オブジェクト」を使うことにしました。混乱しますが、クラスを作成するためにクラスは "object"という名前のクラスから継承しますが、実際にはそのクラスではありませんが、objectから継承することを忘れないでください。

また、新しいスタイルのクラスと古いスタイルのクラスの違いを理解するために、新しいスタイルのクラスは常にobjectクラスまたはobjectから継承された別のクラスから継承しています。

class NewStyle(object):
    pass

別の例は次のとおりです。

class AnotherExampleOfNewStyle(NewStyle):
    pass

古いスタイルの基本クラスは次のようになりますが

class OldStyle():
    pass

そして、古いスタイルの子クラスは次のようになります。

class OldStyleSubclass(OldStyle):
    pass

Old Style基本クラスは他のクラスから継承していないことがわかりますが、Old Styleクラスはもちろん相互に継承できます。オブジェクトから継承することは、特定の機能がすべてのPythonクラスで利用可能であることを保証します。新しいスタイルクラスはPython 2.2で導入されました

30
disp_name

はい、それは 歴史的 です。それがないと、古いスタイルのクラスが作成されます。

古いスタイルのオブジェクトでtype()を使うと、単に "instance"が得られます。新しいスタイルのオブジェクトでは、そのクラスを取得します。

26
knitti

クラス作成ステートメントの構文

class <ClassName>(superclass):
    #code follows

継承元となるスーパークラスが他にない場合は、superclassは常にobjectにする必要があります。これはPythonのすべてのクラスのルートです。

objectは技術的にはPythonの "new-style"クラスのルートです。しかし、今日の新しいスタイルのクラスは、クラスの唯一のスタイルであるのと同じくらい優れています。

しかし、クラスを作成するときに明示的にWord objectを使用しない場合は、他の人が述べたように、Python 3.xはobjectスーパークラスを暗黙的に継承します。しかし、私は明示的なことが暗黙的なことよりも常に優れていると思います(地獄)

参照

6
kmario23