Pythonでは、クラスで変数を宣言するために、それは静的です(次のインスタンスでその値を保持します)。この問題を回避するより良い方法は何ですか?
class Foo():
number = 0
def set(self):
self.number = 1
>>> foo = Foo()
>>> foo.number
0
>>> foo.set()
>>> foo.number
1
>>> new_foo = Foo()
>>> new_foo.number
1
Pythonでは、クラスで変数を宣言するために、それは静的です(次のインスタンスでその値を保持します)。この問題を回避するより良い方法は何ですか?
class Foo():
number = 0
def set(self):
self.number = 1
>>> foo = Foo()
>>> foo.number
0
>>> foo.set()
>>> foo.number
1
>>> new_foo = Foo()
>>> new_foo.number
1
クラスレベルで定義された変数は確かに「静的」ですが、あなたが思っているようには機能しないと思います。ここには、心配する必要がある 2 つのレベルがあります。クラスレベルに属性があり、インスタンスレベルに属性があります。メソッド内で行うときはいつでもself.attribute = ...
、インスタンス レベルで属性を設定しています。Python が属性を検索するときはいつでも、最初にインスタンス レベルを調べます。属性が見つからない場合は、クラス レベルを調べます。
これは少し混乱する可能性があります (特に、属性が変更可能なオブジェクトへの参照である場合)。検討:
class Foo(object):
attr = [] #class level attribute is Mutable
def __init__(self):
# in the next line, self.attr references the class level attribute since
# there is no instance level attribute (yet)
self.attr.append('Hello')
self.attr = []
# Now, we've created an instance level attribute, so further appends will
# append to the instance level attribute, not the class level attribute.
self.attr.append('World')
a = Foo()
print (a.attr) #['World']
print (Foo.attr) #['Hello']
b = Foo()
print (b.attr) #['World']
print (Foo.attr) #['Hello', 'Hello']
__init__
他の人が述べたように、属性をインスタンスに固有にしたい場合は、 (を使用して)インスタンス属性として初期化するだけself.attr = ...
です。 __init__
クラスが初期化されるたびに実行される特別なメソッドです (ここでは説明しないいくつかの例外があります)。
例えば
class Foo(object):
def __init__(self):
self.attr = 0
宣言を省略してください。変数にデフォルト値を提供する場合は、__init__
代わりにメソッドで初期化してください。
class Foo(object):
def __init__(self):
self.number = 0
def set(self):
self.number = 1
>>> foo = Foo()
>>> foo.number
0
>>> foo.set()
>>> foo.number
1
>>> new_foo = Foo()
>>> new_foo.number
0
編集:上記のスニペットの最後の行を置き換えました。1
私の側の単なるタイプミスでしたが、以前は読んでいました。私が留守の間、かなりの混乱を引き起こしたようです。
クラス属性を変更したいかもしれません:
class Foo():
number = 0
def set(self):
Foo.number = 1
オーバーライドする代わりに!