クラス宣言を継承する理由はありますobject
か?
これを行うコードを見つけましたが、その理由がわかりません。
class MyClass(object):
# class code follows...
クラス宣言を継承する理由はありますobject
か?
これを行うコードを見つけましたが、その理由がわかりません。
class MyClass(object):
# class code follows...
回答:
クラス宣言を継承する理由はあります
object
か?
Python 3では、Python 2とPython 3の互換性を除いて、理由はありません。Python 2には多くの理由があります。
Python 2.x(2.2以降)ではobject
、基本クラスとしてのの有無に応じて、2つのクラスのスタイルがあります。
「クラシック」スタイルのクラス:object
基本クラスにはありません:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
「新しい」スタイルのクラス:直接または間接的に(たとえば、組み込み型から継承)、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'>,)
間違いなく、クラスを書くときは常に新しいスタイルのクラスに行きたいと思うでしょう。そうすることの特典はたくさんあり、それらのいくつかをリストアップします:
記述子のサポート。具体的には、次の構成要素が記述子を使用して可能になります。
classmethod
:インスタンスではなく、暗黙の引数としてクラスを受け取るメソッド。staticmethod
:暗黙の引数self
を最初の引数として受け取らないメソッド。property
:属性の取得、設定、削除を管理するための関数を作成します。__slots__
:クラスのメモリ消費を節約し、属性へのアクセスを高速化します。もちろん、制限があります。__new__
静的メソッドは:あなたは、新しいクラスのインスタンスが作成される方法をカスタマイズすることができます。
メソッド解決順序(MRO):呼び出すメソッドを解決しようとするときに、クラスの基本クラスがどの順序で検索されるか。
MROに関連して、をsuper
呼び出します。また、super()
スーパーと見なされます。
から継承しない場合はobject
、これらを忘れてください。「新しい」スタイルのクラスの他の特典とともに、以前の箇条書きのより包括的な説明は、ここで見つけることができます。
新しいスタイルのクラスの欠点の1つは、クラス自体がより多くのメモリを要求することです。ただし、多くのクラスオブジェクトを作成しているのでない限り、これが問題になることはないと思います。これは、ポジティブな海に沈むネガティブなものです。
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では、すべての組み込み型がまだ新しいスタイルのクラスに移植されていなかった時期がありました。
object
。私はPython 2.2.3を使用していますが、簡単なチェックの結果、攻撃者を見つけることができませんでしたが、後でもっと明確にするために答えを書き直します。例を見つけることができれば興味がありますが、私の好奇心はそそられます。
object
ベースにあることを明確にした方がよいと思います。
staticmethod
そして、classmethod
さえ古いスタイルのクラスでうまく動作します。property
sorta は古いスタイルのクラスを読み取るために機能し、書き込みのインターセプトに失敗するだけです(そのため、名前に割り当てた場合、インスタンスは、プロパティをシャドウする特定の名前の属性を取得します)。また__slots__
、の属性アクセス速度の改善は、ほとんどが新しいスタイルのクラス属性アクセスで発生する損失を取り消すことであるため、実際には新しいスタイルのクラスのセールスポイントではありません(ただし、メモリの節約がセールスポイントです)。
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開発者の涙を救うだけです。
__metaclass__ = type
、モジュールの先頭(from __future__ import absolute_import, division, print_function
行の後:-)に配置します); これは、Py2の互換性ハックであり、モジュールで後に定義されるすべてのクラスをデフォルトで新しいスタイルにします。また、Py3では完全に無視されるため(無作為のグローバル変数のみ)、無害です。
はい、これは「新しいスタイル」のオブジェクトです。これはpython2.2で導入された機能でした。
新しいスタイルのオブジェクトには、クラシックオブジェクトとは異なるオブジェクトモデルがあり、古いスタイルのオブジェクト(たとえば、記述子)super()
では正しく動作しないものが@property
あります。新しいスタイルクラスの詳細については、この記事を参照してください。
違いの説明へのSOリンク:Pythonの古いスタイルと新しいスタイルのクラスの違いは何ですか?
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で導入されました
object
はそれほど混乱するものではなく、実際にはかなり標準的です。Smalltalkには、という名前のルートクラスとObject
、という名前のルートメタクラスがありClass
ます。どうして?Dog
犬のクラスと同じように、Object
はオブジェクトClass
のクラスであり、クラスのクラスです。Java、C#、ObjC、Ruby、および現在使用されているほとんどのクラスベースのOO言語では、ルートクラスがあり、Object
Pythonだけでなく、いくつかのバリエーションを名前として使用しています。
はい、歴史的です。それがなければ、それは古いスタイルのクラスを作成します。
type()
古いスタイルのオブジェクトで使用する場合は、「インスタンス」を取得するだけです。新しいスタイルのオブジェクトでは、そのクラスを取得します。
type()
古いスタイルのクラスで使用すると、「type」ではなく「classobj」が取得されます。
クラス作成ステートメントの構文:
class <ClassName>(superclass):
#code follows
特に継承したい他のスーパークラスがない場合、superclass
は常にでなければなりませんobject
。これはPythonのすべてのクラスのルートです。
object
技術的には、Pythonの「新しいスタイルの」クラスのルートです。しかし、今日の新しいスタイルのクラスは、クラスの唯一のスタイルであるのと同じくらい優れています。
ただし、object
クラスの作成時にこの単語を明示的に使用しない場合、他の人が述べたように、Python 3.xはobject
スーパークラスから暗黙的に継承します。しかし、私は明示的が常に暗黙的よりも優れていると思います(地獄)