Counting number of objects

Steve Holden steve at holdenweb.com
Mon Jan 26 09:05:34 EST 2009


Mark Wooding wrote:
> Andreas Waldenburger <geekmail at usenot.de> writes:
> 
>> On Sun, 25 Jan 2009 09:23:35 -0800 (PST) Kottiyath
>> <n.kottiyath at gmail.com> wrote:
>>
>>> class a(object):
>>>     counter = 0
>>>     def __new__(cls, *args, **kwargs):
>>>         a.counter += 1
>>>         return object.__new__(cls, *args, **kwargs)
> 
> Hmm.  Exceptions raised during object creation make this rather
> precarious.  In your code, if object.__new__ raises an exception, the
> counter will end up too high (the __del__ method won't get called in
> this case).
> 
If object.__new__ raises an exception you have bigger problems to worry
about than an object count being wrong.

> One might try to rewrite it:
> 
>         def __new__(cls, *args, **kw):
>           thing = object.__new__(cls, *args, **kw)
>           a.counter += 1
>           return thing
> 
> Now this won't work in subclasses if they also have a __new__ method:
> again, if the subclass's __new__ raises an exception then __del__ won't
> be called and the counter will be too high.
> 
> To make this technique work, I think you need to do the counter
> increment in __init__ rather than __new__, and to set an attribute so
> that __del__ knows whether to do the decrement.  (If a subclass's
> __init__ raises an exception before yours gets called, you don't want to
> do the decrement because that'll leave the counter too low.)
> 
Yes, rather better to do it that way and decouple it from __new__(). Of
course super() might help here, though not everyone approves of it.

>> This looks OK, although I'd suggest using "cls.counter += 1" instead
>> of "a.counter += 1" in the __new__() method. Just seems clearer to me,
>> esp. when you think about subclassing. 
> 
> I'm not sure about clarity, but that would be semantically different.
> The code as written counts all instances of a and its subclasses.  Your
> suggestion would count instances of subclasses independently.  I don't
> know which behaviour the OP would prefer, but I don't think choosing
> between them is a matter of clarity.
> 
Correct, but pointing out the differences has highlighted that is a real
design decision to be made in the event that subclassing is used.

>> Another way to go would be to use the weakref module and create a
>> weakref-set (or list) as the counter. That way you would only need to
>> add the objects in the __new__() method and not worry about removing
>> them. I will admit that this is overengineering the problem a bit, but
>> might be a good exercise.
> 
> This is a better approach, because it avoids the problems with
> exceptions during object construction that I described above.
> 
>>> Another question - unrelated to the major topic:
>>> How much time does it take to be proficient in Python?
>> Don't concern yourself with that question at all, is my advice.
> 
> Indeed.  Besides, it varies an awful lot.
> 
[...]
>>> - or am I just dumb?
>> You're writing programs and you're communicating with like-minded
>> people about your problems (in a socially appropriate way). Not what
>> dumb people do, in my book.
> 
> Absolutely!  Besides, you're asking sensible questions about subtle
> parts of the language -- I wouldn't say that __new__ was beginner
> territory, for example.  So, no, you certainly don't seem dumb to me.
> 
Hear, hear!

regards
 Steve
-- 
Steve Holden        +1 571 484 6266   +1 800 494 3119
Holden Web LLC              http://www.holdenweb.com/




More information about the Python-list mailing list