__del__ and reference count problem

Discussion in 'Python' started by flupke, Apr 21, 2005.

  1. flupke

    flupke Guest

    Hi,

    i'm starting work and a simple database layer and wanted to use the
    __del__ to open and close a connection. However, i get an erro when
    executing this script:

    class Table:
    refcount = 0
    def __init__(self, name):
    self.name = name
    print "table %s " % repr(self)
    Table.refcount += 1
    print "refcount = %s" % str(Table.refcount)

    def __del__(self):
    Table.refcount -= 1
    if (Table.refcount == 0):
    print "Last table standing"
    else:
    print "There is/are still %d table(s) left." % Table.refcount

    def __getitem__(self,item):
    return "not implemented"

    def howMany(self):
    if (Table.refcount == 1):
    print "Only 1 table"
    else:
    print "There are %d tables active." % Table.refcount

    if __name__ == '__main__':
    suppliera = Table("suppliers")
    supplierb = Table("suppliers")
    print "Supplier returned from a %s: %s" % (1, suppliera[1])
    print "Supplier returned from b %s: %s" % (2, supplierb[2])
    suppliera.howMany()
    supplierb.howMany()

    This produces the following output and error:
    table <__main__.Table instance at 0x008D5C10>
    refcount = 1
    table <__main__.Table instance at 0x008D5C38>
    refcount = 2
    Supplier returned from a 1: not implemented
    Supplier returned from b 2: not implemented
    There are 2 tables active.
    There are 2 tables active.
    Exception exceptions.AttributeError: "'NoneType' object has no attribute
    'refcount'" in <bound method Table.__del__ of <__main__.Table instance
    at 0x008D5C10>> ignored
    Exception exceptions.AttributeError: "'NoneType' object has no attribute
    'refcount'" in <bound method Table.__del__ of <__main__.Table instance
    at 0x008D5C38>> ignored

    What am i doing wrong?
    Thanks
    Benedict
     
    flupke, Apr 21, 2005
    #1
    1. Advertising

  2. flupke

    Guest

    Your problem can be simplified :

    class A:
    pop = 11
    def __del__(self):
    print A.pop

    if __name__ == '__main__':
    objA = A()

    Exception exceptions.AttributeError: "'NoneType' object has no
    attribute 'pop'" in <bound method A.__del__ of <__main__.A instance at
    0x01474A08>> ignored

    I got the same error message, and I don't know why ? it looks like the
    class variable can't be accessed from __del__?


    Pujo
     
    , Apr 21, 2005
    #2
    1. Advertising

  3. wrote:

    > Your problem can be simplified :
    >
    > class A:
    > pop = 11
    > def __del__(self):
    > print A.pop
    >
    > if __name__ == '__main__':
    > objA = A()
    >
    > Exception exceptions.AttributeError: "'NoneType' object has no
    > attribute 'pop'" in <bound method A.__del__ of <__main__.A instance at
    > 0x01474A08>> ignored
    >
    > I got the same error message, and I don't know why ? it looks like the
    > class variable can't be accessed from __del__?


    when Python shuts down, modules are sometimes cleaned out before objects
    created from classes in those modules. if you really need to access a global
    object during finalization, you have to hold on to it yourself.

    def __del__(self, A=A):
    print A.pop

    (the best solution is to avoid using finalizers, of course, but that's another story)

    </F>
     
    Fredrik Lundh, Apr 21, 2005
    #3
  4. flupke

    tiissa Guest

    wrote:
    > Your problem can be simplified :
    >
    > class A:
    > pop = 11
    > def __del__(self):
    > print A.pop
    >
    > if __name__ == '__main__':
    > objA = A()
    >
    > I got the same error message, and I don't know why ? it looks like the
    > class variable can't be accessed from __del__?


    It's interesting to note that self.pop instead of A.pop works as expected.
    But I don't know why A.pop doesn't.
     
    tiissa, Apr 21, 2005
    #4
  5. flupke

    Guest

    look at this discussion:
    http://www.dbforums.com/archive/index.php/t-1100372.html

    it looks like we have to use other way, hold the data we want to
    preseve in an object, because it is possible the class is removed
    before the instance cleaned, and we can not expect __del__ 100% in
    handling finalizing process.

    Pujo
     
    , Apr 21, 2005
    #5
  6. flupke

    flupke Guest

    wrote:
    > look at this discussion:
    > http://www.dbforums.com/archive/index.php/t-1100372.html
    >
    > it looks like we have to use other way, hold the data we want to
    > preseve in an object, because it is possible the class is removed
    > before the instance cleaned, and we can not expect __del__ 100% in
    > handling finalizing process.
    >
    > Pujo
    >


    That forum helped. I changed this in my code and it worked
    def __del__(self):
    self.__class__.refcount -= 1
    if (self.__class__.refcount == 0):
    print "Last table standing"
    else:
    print "There is/are still %d table(s) left." %
    self.__class__.refcount

    Output:
    table <__main__.Table instance at 0x009D5B98>
    refcount = 1
    table <__main__.Table instance at 0x009D5BC0>
    refcount = 2
    Supplier returned from a 1: not implemented
    Supplier returned from b 2: not implemented
    There are 2 tables active.
    There are 2 tables active.
    There is/are still 1 table(s) left.
    Last table standing

    Seems to work allright !

    Thanks ! :)
    Benedict
     
    flupke, Apr 21, 2005
    #6
  7. flupke

    Terry Reedy Guest

    <> wrote in message
    news:...
    > it looks like we have to use other way, hold the data we want to
    > preseve in an object, because it is possible the class is removed
    > before the instance cleaned,


    What is removed first is the binding between name A and the class object.
    But the class object still exists (its refcount is > 0) and can be accessed
    via the instance which has a reference to that class object.

    Terry J. Reedy
     
    Terry Reedy, Apr 21, 2005
    #7
  8. flupke

    Terry Reedy Guest

    "tiissa" <> wrote in message
    news:4267f1e0$0$8871$...
    > It's interesting to note that self.pop instead of A.pop works as
    > expected.
    > But I don't know why A.pop doesn't.


    Because the name 'A' is no longer associated with the class object.
    However, self has a reference to the class -- the .__class__ attribute.
    Since self does not itself have a .pop attribute, the attribute resolution
    code then looks at the class.

    Terry J. Reedy
     
    Terry Reedy, Apr 21, 2005
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jane Austine
    Replies:
    2
    Views:
    369
    Steven Taschuk
    Jul 2, 2003
  2. Jane Austine
    Replies:
    1
    Views:
    477
    Erik Max Francis
    Jul 2, 2003
  3. Mike C. Fletcher
    Replies:
    2
    Views:
    317
    Mike C. Fletcher
    Jan 24, 2005
  4. Mike C. Fletcher
    Replies:
    0
    Views:
    429
    Mike C. Fletcher
    Jan 24, 2005
  5. flupke

    __del__ and logging

    flupke, Apr 29, 2005, in forum: Python
    Replies:
    2
    Views:
    387
    flupke
    May 2, 2005
Loading...

Share This Page