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