実際には存在しない違いを入れている気がします。そのような階層は実際にはありません。Python では、すべてがオブジェクトです。これは抽象的な概念ではありませんが、Python を使用するときに作成する構成についてどのように考える必要があるかについて非常に基本的なことです。オブジェクトは、他のオブジェクトの単なる集まりです。新しいスタイルのクラスを使用しているかどうかには微妙な違いがありますが、それ以外の正当な理由がない場合は、新しいスタイルのクラスを使用して想定してください。以下のすべては、新しいスタイルのクラスを想定しています。
オブジェクトがcallableである場合、中かっこのペアの呼び出し構文を使用して、その中に引数を指定して呼び出すことができますmy_callable(arg1, arg2)
。オブジェクトを呼び出し可能にするには、__call__
メソッドを実装する必要があります (または、C レベルの型定義に正しいフィールドを設定する必要があります)。
Python では、オブジェクトに がtype
関連付けられています。タイプは、オブジェクトがどのように構築されたかを説明します。したがって、たとえば、リスト オブジェクトは 型list
で、関数オブジェクトは 型function
です。型自体は typetype
です。組み込み関数を使用して型を見つけることができますtype()
。すべての組み込み型のリストは、pythonドキュメントにあります。型は実際には呼び出し可能なオブジェクトであり、特定の型のインスタンスを作成するために使用されます。
そうです、これで確立されました。特定のオブジェクトの性質は、その型によって定義されます。これは、それが構成するオブジェクトを記述します。質問に戻ります。
まず、あるオブジェクトを構成するオブジェクトの集まりは、そのオブジェクトの属性と呼ばれます。これらの属性は何でもかまいませんが、通常はメソッドと状態を保存する何らかの方法 (int
またはなどの型list
) で構成されます。
関数は 型のオブジェクトですfunction
。重要なことに、それは__call__
メソッドを呼び出し可能にする属性としてメソッドを持っていることを意味します(__call__
メソッドは、それ自体が__call__
メソッドを持つオブジェクトでもあります。それ__call__
はずっと下にあります;)
Pythonの世界では、クラスは型と見なすことができますが、通常は組み込みではない型を参照するために使用されます。これらのオブジェクトは、他のオブジェクトを作成するために使用されます。class キーワードを使用して独自のクラスを定義し、継承する必要がある新しいスタイルのobject
クラス (または他の新しいスタイルのクラス) を作成できます。継承すると、親の型のすべての特性を取得する型を作成し、必要なビットを上書きできます (さらに、必要なビットを上書きできます!)。クラス (またはより一般的には型) を呼び出してインスタンス化すると、そのクラスによって作成された別のオブジェクトが返されます (返されるオブジェクトの作成方法は、クラス オブジェクトを変更することによって奇妙でクレイジーな方法で変更できます)。
メソッドは、属性表記を使用して呼び出される特殊なタイプの関数です。つまり、作成時に 2 つの追加の属性がメソッドに追加されます (これはオブジェクトであることを思い出してください!)im_self
とim_func
. im_self
数文で説明します。im_func
メソッドを実装する関数です。たとえば のようにメソッドが呼び出される場合foo.my_method(10)
、これは を呼び出すことと同じfoo.my_method.im_func(im_self, 10)
です。これが、メソッドを定義するときに、明らかに使用していないように見える追加の最初の引数で定義する理由です (as self
)。
クラスを定義するときに一連のメソッドを記述すると、これらはバインドされていないメソッドになります。そのクラスのインスタンスを作成すると、それらのメソッドは bind になります。バインドされたメソッドを呼び出すと、バインドさim_self
れたメソッドが存在するオブジェクトとして引数が追加されます。クラスのバインドされていないメソッドを呼び出すことはできますが、最初の引数としてクラス インスタンスを明示的に追加する必要があります。
class Foo(object):
def bar(self):
print self
print self.bar
print self.bar.im_self # prints the same as self
bar メソッドのさまざまな明示を呼び出すと何が起こるかを示すことができます。
>>> a = Foo()
>>> a.bar()
<__main__.Foo object at 0x179b610>
<bound method Foo.bar of <__main__.Foo object at 0x179b610>>
<__main__.Foo object at 0x179b610>
>>> Foo.bar()
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)
>>> Foo.bar(a)
<__main__.Foo object at 0x179b610>
<bound method Foo.bar of <__main__.Foo object at 0x179b610>>
<__main__.Foo object at 0x179b610>
上記のすべてをまとめると、次のようにクラスを定義できます。
class MyFoo(object):
a = 10
def bar(self):
print self.a
a
これにより、2 つの属性(値 10 の整数) とbar
バインドされていないメソッドである を持つクラスが生成されます。MyFoo.a
ちょうど 10であることがわかります。
クラスメソッド内外の両方で、実行時に追加の属性を作成できます。次の点を考慮してください。
class MyFoo(object):
a = 10
def __init__(self):
self.b = 20
def bar(self):
print self.a
print self.b
def eep(self):
print self.c
__init__
オブジェクトがクラスから作成された直後に呼び出されるメソッドです。
>>> foo = Foo()
>>> foo.bar()
10
20
>>> foo.eep()
AttributeError: 'MyFoo' object has no attribute 'c'
>>> foo.c = 30
>>> foo.eep()
30
この例では、実行時 (つまり、クラスからオブジェクトが作成された後) に属性をクラス インスタンスに追加する 2 つの方法を示します。
TestCase と TestSuite は、テスト オブジェクトを作成するために使用される単なるクラスであることがおわかりいただけたと思います。テストを書くための便利な機能がいくつかあることを除けば、特別なことは何もありません。それらを思いのままにサブクラス化して上書きすることができます。
特定の点に関しては、メソッドと関数の両方が必要なものを返すことができます。
モジュール、パッケージ、およびスイートの説明はかなり健全なようです。モジュールもオブジェクトであることに注意してください!