クラス宣言がobject
から継承する理由はありますか?
これを実行するコードがいくつか見つかりましたが、その正当な理由が見つかりません。
class MyClass(object):
# class code follows...
クラス宣言が
object
name__から継承する理由はありますか?
tl; dr:Python 3では、Python 2と3の間の互換性は別として、理由なし。Python2では多くの理由).
Python 2.x(2.2以降)には、基本クラスとしてのobject
name__の有無に応じて、2つのクラスのスタイルがあります。
"クラシック"スタイル classes:object
name__を基本クラスとして持ちません。
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
"new" style classes:直接または間接的に(たとえば 組み込み型から継承 ))、object
name__を基本クラスとして持っています。
>>> 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
name__ :インスタンスの代わりに暗黙の引数としてクラスを受け取るメソッド。staticmethod
name__ :暗黙の引数self
name__を最初の引数として受け取らないメソッド。property
name__ :付きのプロパティ属性の取得、設定、削除を管理する関数を作成します。__slots__
:クラスのメモリ消費量を節約し、属性アクセスも速くなります。もちろん、それは 制限を課します 。__new__
staticメソッド:新しいクラスインスタンスの作成方法をカスタマイズできます。
メソッド解決順序(MRO) :呼び出すメソッドを解決しようとしたときに、クラスの基本クラスがどの順序で検索されるか。
MROに関連して、 super
name__は を呼び出します。 super()
もsuperと見なされます。
object
name__から継承しない場合は、これらを忘れてください。 "新しい"スタイルクラスの他の特典と一緒に以前の箇条書きの点のより徹底的な説明は見つけることができます ここ 。
新しいスタイルのクラスの欠点の1つは、クラス自体がより多くのメモリを必要とすることです。あなたが多くのクラスオブジェクトを作成しているのでなければ、しかし、私はこれが問題になるとは思わないし、それは肯定的な海の中で否定的な沈み込みである。
Python 3では、物事は単純化されています。新しいスタイルのクラスだけが存在し(単純にクラスと呼ばれる)、object
name__を追加する唯一の違いは、さらに8文字を入力する必要があることです。この:
class ClassicSpam:
pass
これと完全に同等です(それらの名前を除いて:-)。
class NewSpam(object):
pass
そしてこれに:
class Spam():
pass
すべての__bases__
にobject
name__があります。
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
Python 2の場合: 常にobject
name__から明示的に継承する。特典を受けましょう。
Python 3の場合: Pythonに依存しないようにする、つまりPython 2とPython 3の両方で機能する必要があるコードを作成している場合はobject
name__を継承Pythonがあなたのために舞台裏でそれを挿入して以来の違い。
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の開発者たちを涙から救ってください。
はい、これは「新しいスタイル」のオブジェクトです。これはpython2.2で導入された機能です。
新しいスタイルオブジェクトは、古典的なオブジェクトとは異なるオブジェクトモデルを持っています。例えば、super()
、@property
、記述子など、古いスタイルのオブジェクトでは正しく動作しないものがあります。新しいスタイルクラスが何であるかの良い説明については この記事 を見てください。
違いについての説明はSOリンク: Pythonの古いスタイルと新しいスタイルのクラスの違いは何ですか?
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で導入されました
はい、それは 歴史的 です。それがないと、古いスタイルのクラスが作成されます。
古いスタイルのオブジェクトでtype()
を使うと、単に "instance"が得られます。新しいスタイルのオブジェクトでは、そのクラスを取得します。
クラス作成ステートメントの構文
class <ClassName>(superclass):
#code follows
継承元となるスーパークラスが他にない場合は、superclass
は常にobject
にする必要があります。これはPythonのすべてのクラスのルートです。
object
は技術的にはPythonの "new-style"クラスのルートです。しかし、今日の新しいスタイルのクラスは、クラスの唯一のスタイルであるのと同じくらい優れています。
しかし、クラスを作成するときに明示的にWord object
を使用しない場合は、他の人が述べたように、Python 3.xはobject
スーパークラスを暗黙的に継承します。しかし、私は明示的なことが暗黙的なことよりも常に優れていると思います(地獄)