最初の例では、インスタンス属性を定義しています。2 つ目は、クラスの属性です。
クラス属性は、そのクラスのすべてのインスタンス間で共有されます。インスタンス属性は、その特定のインスタンスによって「所有」されます。
例による違い
違いを理解するために、例を使用してみましょう。
インスタンス属性を持つクラスを定義します。
class MyClassOne:
def __init__(self):
self.country = "Spain"
self.city = "Barcelona"
self.things = []
そして、クラス属性を持つもの:
class MyClassTwo:
country = "Spain"
city = "Barcelona"
things = []
そして、これらのオブジェクトの 1 つに関する情報を出力する関数:
def information(obj):
print "I'm from {0}, ({1}). I own: {2}".format(
obj.city, obj.country, ','.join(obj.things))
MyClassOne
2 つのオブジェクトを作成し、1 つを Milan に変更して、Milan に「何か」を与えましょう。
foo1 = MyClassOne()
bar1 = MyClassOne()
foo1.city = "Milan"
foo1.country = "Italy"
foo1.things.append("Something")
を呼び出すとinformation()
、期待どおりの値が得られます。foo1
bar1
>>> information(foo1)
I'm from Milan, (Italy). I own: Something
>>> information(bar1)
I'm from Barcelona, (Spain). I own:
ただし、まったく同じことを行うと、 のインスタンスを使用MyClassTwo
して、クラス属性がインスタンス間で共有されることがわかります。
foo2 = MyClassTwo()
bar2 = MyClassTwo()
foo2.city = "Milan"
foo2.country = "Italy"
foo2.things.append("Something")
そして、電話information()
...
>>> information(foo2)
I'm from Milan, (Italy). I own: Something
>>> information(bar2)
I'm from Barcelona, (Spain). I own: Something
ご覧のとおり、 -things
はインスタンス間で共有されています。things
各インスタンスがアクセスできるリストへの参照です。したがって、任意のインスタンスからのものに追加すると、同じリストが他のすべてのインスタンスで表示されます。
文字列変数でこの動作が見られない理由は、実際には新しい変数をインスタンスに割り当てているためです。この場合、その参照はインスタンスによって「所有」され、クラス レベルでは共有されません。説明するために、新しいリストをのに割り当てましょうbar2
。
bar2.things = []
これにより、次の結果が得られます。
>>> information(foo2)
I'm from Milan, (Italy). I own: Something
>>> information(bar2)
I'm from Barcelona, (Spain). I own: