2009年1月19日月曜日

name mangling

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
どう説明するのがいいのかしら?Private Variablesとかをわかるように説明しないといけないのか。継承側で__closedをインスタンスごとに持たせるのかどうかは継承側しだい。でもそこでの代入で親クラスのcls.__closedを書き換えちゃまずそうだよね。兄弟間で親を書き換えてコンフリクトがおこるのでは困る。

説明したいコードはこれ。

__closed = False

def close(self) -> None:
"""Flush and close the IO object.

This method has no effect if the file is already closed.
"""
if not self.__closed:
try:
self.flush()
except IOError:
pass # If flush() fails, just give up
self.__closed = True


リンク先のドキュメントを確認していて、こんなくだりを発見。

(Buglet: derivation of a class with the same name as the base class makes use of private variables of the base class possible.)

あ・・・。

import hoge

class X(hoge.X):
....

なコード書いてた。manglingの観点からはよくないのだな。
_ + "親クラスの名前" + _ + "自分の名前" + __ + "変数名"
とかにしてくれればいいのに。


import sys
assert sys.version_info[0] == 2

class A(object):
__a = 1
def foo(self):
try:
exec 'print self._A__a'
except AttributeError, e:
print e
def bar(self):
try:
exec 'print self.__a'
except AttributeError, e:
print e
a = A()
a.foo()
a.bar()

これを実行して見ると、classが生成されたときに代入だけでなくすべての参照が__aから_A__aに書き換わってしまい、それはmethodの中のアクセスも例外じゃない。文字列で持っていれば書き換わらないのでexecで動的に後からアクセスするとattributeが発見できず、エラーになる。

最初にもどると、__closeの意図が理解できない。継承したクラスでcloseをかならずoverrideしなきゃいけないように思える。気のせいだろうか??しかも__closeにTrueを代入しているコードが見当たらないので、if not ...のthen節は実行されることが無い気がする。

0 件のコメント: