Mark Wooding wrote: > Andreas Waldenburger <geekm...@usenot.de> writes: > >> On Sun, 25 Jan 2009 09:23:35 -0800 (PST) Kottiyath >> <n.kottiy...@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/ -- http://mail.python.org/mailman/listinfo/python-list