初めてのPython(24章後編)
名前空間 = ディクショナリ
サブクラスにスーパークラスの属性が継承される時に起こるのは「ディクショナリのリンク」
[kobakoba0723@fedora13-intel64 ~]$ cat namespace.py #!/usr/bin/env python class C1(object): c1_data = 1 def __init__(self, value): self.name = value def printname(self): print self.name class C2(object): c2_data = 2 def __init__(self, value): self.age = value def printage(self): print self.age class C3(C1, C2): def __init__(self, name, age, tel): C1.__init__(self, name) C2.__init__(self, age) self.tel = tel def printdata(self): self.printname() self.printage() class C4(C2, C1): def __init__(self, name, age, address): C1.__init__(self, name) C2.__init__(self, age) self.address = address def printdata(self): self.printname() self.printage() if __name__ == '__main__': x = C3('taro', 28, '012-3456-7890') y = C4('jiro', 28, 'Japan') print 'x.__class__', x.__class__ print 'x.__dict__:', x.__dict__ print print 'y.__class__:', y.__class__ print 'y.__dict__:', y.__dict__ print print '[C1.__bases__]' print '\t',C1.__bases__ print '[C2.__bases__]' print '\t',C2.__bases__ print '[C3.__bases__]' print '\t',C3.__bases__ print '[C4.__bases__]' print '\t',C4.__bases__ print print '[C1.__dict__]' for key in C1.__dict__.keys(): print '\t(key, value) = (%s, %s)' % (key, C1.__dict__[key]) print '[C2.__dict__]' for key in C2.__dict__.keys(): print '\t(key, value) = (%s, %s)' % (key, C2.__dict__[key]) print '[C3.__dict__]' for key in C3.__dict__.keys(): print '\t(key, value) = (%s, %s)' % (key, C3.__dict__[key]) print '[C4.__dict__]' for key in C4.__dict__.keys(): print '\t(key, value) = (%s, %s)' % (key, C4.__dict__[key]) print print 'x.name:', x.name print 'x.tel:', x.tel print 'x.c1_data:', x.c1_data print 'x.c2_data:', x.c2_data [kobakoba0723@fedora13-intel64 ~]$ python namespace.py x.__class__ <class '__main__.C3'> x.__dict__: {'age': 28, 'tel': '012-3456-7890', 'name': 'taro'} y.__class__: <class '__main__.C4'> y.__dict__: {'age': 28, 'name': 'jiro', 'address': 'Japan'} [C1.__bases__] (<type 'object'>,) [C2.__bases__] (<type 'object'>,) [C3.__bases__] (<class '__main__.C1'>, <class '__main__.C2'>) [C4.__bases__] (<class '__main__.C2'>, <class '__main__.C1'>) [C1.__dict__] (key, value) = (__module__, __main__) (key, value) = (c1_data, 1) (key, value) = (printname, <function printname at 0x7fd9b0dcec08>) (key, value) = (__dict__, <attribute '__dict__' of 'C1' objects>) (key, value) = (__weakref__, <attribute '__weakref__' of 'C1' objects>) (key, value) = (__doc__, None) (key, value) = (__init__, <function __init__ at 0x7fd9b0dceb90>) [C2.__dict__] (key, value) = (__module__, __main__) (key, value) = (printage, <function printage at 0x7fd9b0dcecf8>) (key, value) = (__dict__, <attribute '__dict__' of 'C2' objects>) (key, value) = (c2_data, 2) (key, value) = (__weakref__, <attribute '__weakref__' of 'C2' objects>) (key, value) = (__doc__, None) (key, value) = (__init__, <function __init__ at 0x7fd9b0dcec80>) [C3.__dict__] (key, value) = (__module__, __main__) (key, value) = (printdata, <function printdata at 0x7fd9b0dcede8>) (key, value) = (__doc__, None) (key, value) = (__init__, <function __init__ at 0x7fd9b0dced70>) [C4.__dict__] (key, value) = (__module__, __main__) (key, value) = (printdata, <function printdata at 0x7fd9b0dceed8>) (key, value) = (__doc__, None) (key, value) = (__init__, <function __init__ at 0x7fd9b0dcee60>) x.name: taro x.tel: 012-3456-7890 x.c1_data: 1 x.c2_data: 2 [kobakoba0723@fedora13-intel64 ~]$
オブジェクトツリーの検索が、「リンクされたディクショナリに対して順に行う」ってことだったから、
x.__dict__/y.__dict__ で age/name の出力順が入れ替わってると期待したけど、
ちゃんと考えるとディクショナリなんだから、順番には意味がないんだった。
だから、たとえ入れ替わってたとしても”たまたま”そうなったってことにしかならない。
とはいえ、__bases__属性の結果はスーパークラスとして指定した順にちゃんと並んでる。
ここをどうにかして使うんだろうなぁ。
あと、サブクラスのインスタンス属性なのか、スーパークラスのインスタンス属性なのかの見分けもどうやってるんだろう。
インスタンスオブジェクトの__dict__を見ただけだと、どっちも同格のものとして見えてしまう。
それに、.__class__.__dict__にはサブクラスのインスタンス属性は現れない。
当然、.__bases__[N].__dict__にもスーパークラスのインスタンス属性は現れない