Python объект, содержащий dict () объектов - PullRequest
0 голосов
/ 07 июня 2011

Вот тестовый пример, который я создал для обнаруженной проблемы.

По какой-то причине dict () 'l' в B (), похоже, не содержит правильное значение. Смотрите вывод ниже на моей Linux 11.04 Ubuntu, python 2.7.1 +.

class A():
    name = None
    b = None
    def __init__(self, name, bname, cname, dname):
        self.name = name
        print "A: name", name
        self.b = B(name, bname, cname, dname)
        print "A self.b:", self.b

class B():
    name = None
    l = dict()
    c = None
    def __init__(self, name, bname, cname, dname):
        self.aname = name
        self.name = bname
        print " B: name", bname
        self.c = C(bname, cname, dname)
        self.l["bb"] = self.c
        print " B self:", self
        print " B self.c:", self.c
        print " B self.l[bb]:", self.l["bb"], "<<< OK >>>"

    def dump(self):
        print " A: name", self.aname
        print " B: name", self.name
        for i in self.l:
            print " B: i=", i, "self.l[i]", self.l[i], "<<< ERROR >>>"

class C():
    name = None
    l = dict()
    d = None
    def __init__(self, bname, cname, dname):
        self.bname = bname
        self.cname = cname
        print "  B: name", bname
        print "  C: name", cname
        print "  C self:", self

    def dump(self):
        print "  B name:", self.bname
        print "  C name:", self.cname

a1 = A("a1", "b1", "c1", "d1")
a2 = A("a2", "b2", "c2", "d2")
a3 = A("a3", "b3", "c3", "d3")

a1.b.dump()
a1.b.c.dump()
a2.b.dump()
a2.b.c.dump()
a3.b.dump()
a3.b.c.dump()

Вывод на мою машину:

    $ python bedntest.py 
A: name a1
 B: name b1
  B: name b1
  C: name c1
  C self: <__main__.C instance at 0xb76f3a6c>
 B self: <__main__.B instance at 0xb76f388c>
 B self.c: <__main__.C instance at 0xb76f3a6c>
 B self.l[bb]: <__main__.C instance at 0xb76f3a6c> <<< OK >>>
A self.b: <__main__.B instance at 0xb76f388c>
A: name a2
 B: name b2
  B: name b2
  C: name c2
  C self: <__main__.C instance at 0xb76f3acc>
 B self: <__main__.B instance at 0xb76f3aac>
 B self.c: <__main__.C instance at 0xb76f3acc>
 B self.l[bb]: <__main__.C instance at 0xb76f3acc> <<< OK >>>
A self.b: <__main__.B instance at 0xb76f3aac>
A: name a3
 B: name b3
  B: name b3
  C: name c3
  C self: <__main__.C instance at 0xb76f3b2c>
 B self: <__main__.B instance at 0xb76f3b0c>
 B self.c: <__main__.C instance at 0xb76f3b2c>
 B self.l[bb]: <__main__.C instance at 0xb76f3b2c> <<< OK >>>
A self.b: <__main__.B instance at 0xb76f3b0c>
 A: name a1
 B: name b1
 B: i= bb self.l[i] <__main__.C instance at 0xb76f3b2c> <<< ERROR >>>
  B name: b1
  C name: c1
 A: name a2
 B: name b2
 B: i= bb self.l[i] <__main__.C instance at 0xb76f3b2c> <<< ERROR >>>
  B name: b2
  C name: c2
 A: name a3
 B: name b3
 B: i= bb self.l[i] <__main__.C instance at 0xb76f3b2c> <<< ERROR >>>
  B name: b3
  C name: c3

Насколько я понимаю, строки выше:

B: i= bb self.l[i] <__main__.C instance at 0xb76f3b2c> <<< ERROR >>>

все должны содержать уникальный экземпляр C (), как видно во время инициализации, а не последний созданный экземпляр (см. Строки <<< OK >>>).

Что здесь произошло?

Ответы [ 2 ]

6 голосов
/ 07 июня 2011

Произошло то, что вы создали атрибут класса.Вместо этого создайте атрибут экземпляра, создав его экземпляр в __init__().

1 голос
/ 07 июня 2011

Похоже, вы пытаетесь "объявить" атрибуты экземпляра на уровне класса. Атрибуты класса имеют свои специфические применения в Python, и неправильно помещать их туда, если вы не собираетесь когда-либо использовать атрибуты класса

class A():
    name = None  # Don't do this
    b = None     # Don't do this
    def __init__(self, name, bname, cname, dname):
        self.name = name
        print "A: name", name
        self.b = B(name, bname, cname, dname)
        print "A self.b:", self.b

В class B вы создали атрибут класса l. Поскольку экземпляр не имеет своего собственного атрибута l, он использует атрибут класса.

Вместо этого вы могли бы написать свой класс В вот так

class B():
    def __init__(self, name, bname, cname, dname):
        self.aname = name
        self.name = bname
        self.l = dict()
        print " B: name", bname
        self.c = C(bname, cname, dname)
        self.l["bb"] = self.c
        print " B self:", self
        print " B self.c:", self.c
        print " B self.l[bb]:", self.l["bb"], "<<< OK >>>"

...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...