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


1244

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

これを行うコードを見つけましたが、その理由がわかりません。

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

2
これにより、新しいスタイルのクラスが作成されます。
SLak

116
この質問への答え(単純ですが)を見つけるのは非常に困難です。「Pythonオブジェクトベースクラス」などのグーグルのオブジェクトには、オブジェクト指向プログラミングに関するチュートリアルのページとページが表示されます。これは、検索用語「旧対新スタイルのPythonオブジェクト」に私を導いた最初のリンクであるため、Upvoting
vastlysuperiorman

回答:


764

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

Python 3では、Python 2とPython 3の互換性を除いて、理由はありません。Python 2には多くの理由があります。


Python 2.xストーリー:

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

  1. 「クラシック」スタイルのクラス:object基本クラスにはありません:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
  2. 「新しい」スタイルのクラス:直接または間接的に(たとえば、組み込み型から継承)、object基本クラスとして持っています。

    >>> 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'>,)

間違いなく、クラスを書くときは常に新しいスタイルのクラスに行きたいと思うでしょう。そうすることの特典はたくさんあり、それらのいくつかをリストアップします:

  • 記述子のサポート。具体的には、次の構成要素が記述子を使用して可能になります。

    1. classmethod:インスタンスではなく、暗黙の引数としてクラスを受け取るメソッド。
    2. staticmethod:暗黙の引数selfを最初の引数として受け取らないメソッド。
    3. プロパティwith property:属性の取得、設定、削除を管理するための関数を作成します。
    4. __slots__:クラスのメモリ消費を節約し、属性へのアクセスを高速化します。もちろん、制限があります。
  • __new__静的メソッドは:あなたは、新しいクラスのインスタンスが作成される方法をカスタマイズすることができます。

  • メソッド解決順序(MRO):呼び出すメソッドを解決しようとするときに、クラスの基本クラスがどの順序で検索されるか。

  • MROに関連して、をsuper呼び出します。また、super()スーパーと見なされます。

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

新しいスタイルのクラスの欠点の1つは、クラス自体がより多くのメモリを要求することです。ただし、多くのクラスオブジェクトを作成しているのでない限り、これが問題になることはないと思います。これは、ポジティブな海に沈むネガティブなものです。


Python 3.xストーリー:

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

class ClassicSpam:
    pass

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

class NewSpam(object):
     pass

そしてこれに:

class Spam():
    pass

すべてがobject彼らの中にあり__bases__ます。

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

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

Python 2では、 常にobject明示的に継承します。特典を取得します。

Python 3:object Pythonにとらわれないコードを記述している場合は継承します。つまり、Python 2とPython 3の両方で機能する必要があります。それ以外の場合は、Pythonが挿入するため、違いはありません。舞台裏。


「基本クラスとしての組み込み型の有無に応じて」=>実際には、「基本クラスとしての組み込み型の不在または存在」ではなく、クラスが-から直接または間接的に継承するどうobject。IIRCでは、すべての組み込み型がまだ新しいスタイルのクラスに移植されていなかった時期がありました。
bruno desthuilliers 2018年

@brunodesthuilliers私の印象では、すべての組み込み型はから継承されていましたobject。私はPython 2.2.3を使用していますが、簡単なチェックの結果、攻撃者を見つけることができませんでしたが、後でもっと明確にするために答えを書き直します。例を見つけることができれば興味がありますが、私の好奇心はそそられます。
Dimitris Fasarakis Hilliard 2018

正直に言えば(以前のコメントの「IIRC」を参照)、この点について101%はわかりません(新しいスタイルのクラスが導入されたときに、すべての組み込み型がすでに新しいスタイルのクラスに変換されていたかどうか)-私は単純かもしれません間違っている、またはこれは一部の標準ライブラリの(組み込みではない)タイプにのみ関係している可能性があります。しかし、それでも、新しいスタイルのクラスを構成する要素がそのobjectベースにあることを明確にした方がよいと思います。
Bruno desthuilliers

7
stackoverflowが悪すぎると、これらのちょっとした回答に対してupvote = upvote + 1しか行われません
。upvote

1
staticmethodそして、classmethodさえ古いスタイルのクラスでうまく動作します。propertysorta は古いスタイルのクラスを読み取るために機能し、書き込みのインターセプトに失敗するだけです(そのため、名前に割り当てた場合、インスタンスは、プロパティをシャドウする特定の名前の属性を取得します)。また__slots__、の属性アクセス速度の改善は、ほとんどが新しいスタイルのクラス属性アクセスで発生する損失を取り消すことであるため、実際には新しいスタイルのクラスのセールスポイントではありません(ただし、メモリの節約がセールスポイントです)。
ShadowRanger

540

Python 3

  • class MyClass(object): =新しいスタイルのクラス
  • class MyClass:=新しいスタイルのクラス(暗黙的にから継承object

Python 2

  • class MyClass(object): =新しいスタイルのクラス
  • class MyClass:= 古いスタイルのクラス

説明

Python 3.xで基本クラスを定義する場合object、定義からを削除できます。しかし、これは追跡が非常に難しい問題の扉を開く可能性があります…

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開発者の涙を救うだけです。


13
「Python 3.xで基本クラスを定義するとき、オブジェクトを定義から削除できます。しかし、これは追跡が非常に難しい問題の扉を開く可能性があります...」どのような問題を参照していますか?
アイディス2014

6
@Aidis:Py2とPy3の両方で実行されるコードはPy3では問題ないが、新しいスタイルのクラス機能に依存している場合はPy2で機能しないことを意味すると思います。個人的には、そのようなコードを記述している場合は、明示的な継承を省略して__metaclass__ = type、モジュールの先頭(from __future__ import absolute_import, division, print_function行の後:-)に配置します); これは、Py2の互換性ハックであり、モジュールで後に定義されるすべてのクラスをデフォルトで新しいスタイルにします。また、Py3では完全に無視されるため(無作為のグローバル変数のみ)、無害です。
ShadowRanger 16

400

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

新しいスタイルのオブジェクトには、クラシックオブジェクトとは異なるオブジェクトモデルがあり、古いスタイルのオブジェクト(たとえば、記述子)super()では正しく動作しないものが@propertyあります。新しいスタイルクラスの詳細については、この記事を参照してください。

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


110
+1これ。あなたが唯一の継承に必要なので注意が古いスタイルのクラスは、Pythonの3になくなっていることobject2. Pythonで

9
これは本当の答えではありません。私は他の記事への参照を与えるだけです。ヤリンの答えはこの質問の答えとして受け入れられるべきだと思います。
alwbtc 2016年

2
@alwbtc:この回答にも新しいものがあります。たとえば、 "super()"について言及すると、別の重要な[ここ](stackoverflow.com/questions/576169/…)に導かれました。
ViFI 2016年

34

Learn Python the Hard Wayの歴史:

Pythonのクラスの元の表現は、多くの深刻な方法で壊れていました。この欠陥が認識されるまでには、すでに手遅れであり、彼らはそれをサポートしなければなりませんでした。問題を修正するために、「古いクラス」が機能し続けるように「新しいクラス」のスタイルが必要でしたが、新しいより正しいバージョンを使用できます。

彼らは、クラスを作成するために継承する「クラス」として、小文字の「オブジェクト」という単語を使用することを決定しました。混乱を招きますが、クラスは「オブジェクト」という名前のクラスから継承してクラスを作成しますが、オブジェクトではなくクラスですが、オブジェクトから継承することを忘れないでください。

また、新しいスタイルのクラスと古いスタイルのクラスの違いを知らせるためだけに、新しいスタイルのクラスは常に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で導入されました


8
ルートクラスの呼び出しobjectはそれほど混乱するものではなく、実際にはかなり標準的です。Smalltalkには、という名前のルートクラスとObject、という名前のルートメタクラスがありClassます。どうして?Dog犬のクラスと同じように、ObjectはオブジェクトClassのクラスであり、クラスのクラスです。Java、C#、ObjC、Ruby、および現在使用されているほとんどのクラスベースのOO言語では、ルートクラスがあり、ObjectPythonだけでなく、いくつかのバリエーションを名前として使用しています。
abarnert

30

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

type()古いスタイルのオブジェクトで使用する場合は、「インスタンス」を取得するだけです。新しいスタイルのオブジェクトでは、そのクラスを取得します。


また、type()古いスタイルのクラスで使用すると、「type」ではなく「classobj」が取得されます。
ジョエル・シェーグレン

7

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

class <ClassName>(superclass):
    #code follows

特に継承したい他のスーパークラスがない場合、superclassは常にでなければなりませんobject。これはPythonのすべてのクラスのルートです。

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

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

参照

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.