Re: Python 2.6 Deprecation Warnings with __new__ — Can someone explain why?

rh0dium steven.klass at gmail.com
Mon Oct 26 00:04:16 EDT 2009


Carl,

First off - Thanks your post was exactly the kind of informative
example driven learnings that help — Thanks!!



On Oct 22, 9:05 pm, Carl Banks <pavlovevide... at gmail.com> wrote:

>
> Before we get into object semantics, I'm not sure why you'd need to
> override __new__ for Borg pattern, unless they're working around some
> edge cases or something.
> For that matter you shouldn't need args and kwargs either, you know
> what the arguments to your function are.

Good point — admitadly I blindly followed Alex M's advice.  I am still
working my way through this.  Point taken.

>
> This should suffice for you:
>
> class Borg(object):
>     __shared_state = {}
>     def __init__(self, noSend=False,reportLevel=30,
>                  reportMethods="BaseReport",
>                  contacts=None):
>         self.__dict__ = self.__shared_state
>         self.noSend = noSend
>         self.reportLevel = reportLevel
>         self.reportMethods = reportMethods
>         self.contacts = contacts
>
> This (as well as your class) will update the shared state for all Borg
> objects whenever you instantiate a new Borg object.  That might be
> what you want, but be aware.


Now the real question I have on this is scalability.  The real
advantage to using *args and **kwargs is that down the road (through
inheritance/polymorphism) I may not know what I'm being given (isn't
that the essence of duck-typing). My long standing belief is that by
using *args and **kwargs I plan for future additions with minimal
changes to my code.  So doesn't restricting this just defeat the
purpose?

>
> > In my case the args that it dumps them into a black hold is simply not
> > true.
>
> Actually it is.
>
> > I want an unknown set of args and kwargs to simply be forwarded
> > onto init.  So what's the problem with this??
>
> The problem is that __new__ doesn't forward the arguments to
> __init__.  Look at what happens when you call this class:
>
> class X(object):
>     def __new__(cls,*args,**kwargs):
>         return object.__new__(cls)
>     def __init__(self,*args,**kwargs):
>         print args, kwargs
>
> X(1,2,q=3,g=4)
>
> Note that *args and **kwargs are not passed to object.__new__, but
> nevertheless __init__ is still called with them.
>
> What's actually happens is that the type object's __call__ method
> passes the same arguments to both __new__ and __init__.
>
> The fact is, object.__new__ does nothing at all with the args and
> kwargs arguments, it just ignores them.  So, when calling
> object.__new__, don't pass them to it.

So what is the point of using __new__?  After a bit of reading
http://docs.python.org/reference/datamodel.html 3.4.1 and I think I
understand.  More to the point you made above.  The whole necessity of
__new__ above makes most of this moot ;)


Once again thanks Carl for your great response!!

Steven



More information about the Python-list mailing list