以下のようなプログラムはクラス内変数のtestが外部から操作可能になっており、バグを生む可能性があります。
class MyClass(object):
def __init__(self):
self.test = 'test'
t = MyClass()
print(t.test)
# 直接編集できてしまう
t.test = 'test2'
print(t.test)
test
test2
関数内の変数にダブルアンダースコアを付けることで外部から編集できなくさせることができます。
ダブルアンダースコアをつけても以下の形でsetterを使わずに編集可能なようです。
class MyClass(object):
def __init__(self):
self.__test = 'test'
@property
def test(self):
return self.__test
t = MyClass()
print(t.test)
# setterを使わずに編集
t._MyClass__test = 'test2'
print(t._MyClass__test)
# 普通に編集はできない
t.__test = 'test3'
print(t.test)
test
test2
test2
pep8にも「Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.」というように書かれており、変数をプライベートっぽくするためにダブルアンダースコアをつけるのは推奨されていないようです。プライベート変数にしたい場合には先頭にシングルアンダースコアをつけることでそれをプライベート変数であると示すのが正しいやり方だそうです。
class MyClass(object):
def __init__(self):
self._test = 'test'
@property
def test(self):
return self._test
@test.setter
def test(self, value):
self._test = value
t = MyClass()
print(t.test)
# setterを使って編集
t.test = 'test2'
print(t.test)
test
test2
実際にはsetterを使わずとも編集、操作できてしまう点は注意が必要です。
class MyClass(object):
def __init__(self):
self._test = 'test'
@property
def test(self):
return self._test
@test.setter
def test(self, value):
self._test = value
t = MyClass()
print(t.test)
# setterを使って編集
t.test = 'test2'
print(t.test)
# setterを使わずに編集
t._test = 'test3'
print(t._test)