バリケンのPython日記 RSSフィード

2008-10-15

[] クラス(8)  クラス(8) - バリケンのPython日記 を含むブックマーク はてなブックマーク -  クラス(8) - バリケンのPython日記  クラス(8) - バリケンのPython日記 のブックマークコメント

前回もちょこっと触れたけど、Pythonではインスタンス変数カプセル化されないよ。だから、再代入できちゃうよ。

>>> class Person(object):
...   def __init__(self, name, age):
...     self.name = name
...     self.age = age
...   def say(self):
...     print 'My name is %s, I am %d years old.' % (self.name, self.age)
...
>>> person = Person('Taro', 15)
>>> person.say()
My name is Taro, I am 15 years old.
>>> person.name = 'Hanako'
>>> person.age = 17
>>> person.say()
My name is Hanako, I am 17 years old.
>>>

これを防ぐには、インスタンス変数名の先頭にアンダースコアを二つつけるよ。

>>> class Person(object):
...   def __init__(self, name, age):
...     self.__name = name
...     self.__age = age
...   def say(self):
...     print 'My name is %s, I am %d years old.' % (self.__name, self.__age)
...
>>> person = Person('Taro', 15)
>>> person.say()
My name is Taro, I am 15 years old.
>>> person.__name = 'hanako'
>>> person.__age = 17
>>> person.say()
My name is Taro, I am 15 years old.
>>>

実際にはPythonの内部的に別の変数名に変換('_Person__age', '_Person__name')しているだけなので、本気で書き換えようと思えば書き換えることができちゃうよ。

>>> dir(person)
['_Person__age', '_Person__name', '__age', '__class__', '__delattr__', '__dict__
', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__name'
, '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__'
, '__weakref__', 'say']
>>> person._Person__name = 'Hanako'
>>> person._Person__age = 17
>>> person.say()
My name is Hanako, I am 17 years old.
>>>
トラックバック - http://python.g.hatena.ne.jp/muscovyduck/20081015