Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder1.enfer-du-nord.net!newsfeed.eweka.nl!eweka.nl!feeder3.eweka.nl!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'instance,': 0.05; '"""': 0.07; 'happen,': 0.07; 'initialize': 0.07; 'override': 0.07; 'see:': 0.07; 'type,': 0.07; 'python': 0.08; 'ah,': 0.09; 'callable.': 0.09; 'created,': 0.09; 'descriptor': 0.09; 'instance.': 0.09; 'variations': 0.09; 'things.': 0.12; 'stored': 0.13; 'thanks!': 0.14; 'method.': 0.15; "2's": 0.16; '__init__': 0.16; 'bound;': 0.16; 'called,': 0.16; 'creation,': 0.16; 'creation.': 0.16; 'methods,': 0.16; 'returned,': 0.16; 'safe,': 0.16; 'unbound': 0.16; 'cc:addr:python-list': 0.16; 'mon,': 0.16; 'wrote:': 0.18; '>>>': 0.18; 'arguments': 0.18; 'instance': 0.18; 'appears': 0.19; 'cc:no real name:2**0': 0.20; 'trying': 0.21; '(most': 0.21; 'detect': 0.21; 'dec': 0.22; "doesn't": 0.22; 'assume': 0.22; 'header:In-Reply-To:1': 0.22; 'appear': 0.23; 'complete,': 0.23; 'cc:2**0': 0.24; 'static': 0.24; 'traceback': 0.24; 'do,': 0.25; 'says': 0.25; 'guess': 0.26; "i'm": 0.26; 'function': 0.27; 'process,': 0.28; 'bit': 0.28; 'worked': 0.29; 'cc:addr:python.org': 0.29; 'pm,': 0.29; 'class': 0.29; 'confused': 0.30; 'kelly': 0.30; 'objects.': 0.30; 'typeerror:': 0.30; 'does': 0.32; 'cases': 0.32; 'wondering': 0.32; 'objects': 0.32; 'tue,': 0.32; 'pretty': 0.32; "isn't": 0.33; 'header:User- Agent:1': 0.33; 'actually': 0.33; 'rather': 0.33; 'that,': 0.33; 'there': 0.33; 'object': 0.33; 'it.': 0.34; 'someone': 0.34; 'normally': 0.34; 'things': 0.34; 'last):': 0.34; 'leaves': 0.34; 'themselves,': 0.34; 'typical': 0.34; 'thank': 0.35; 'unless': 0.35; 'url:python': 0.36; 'file': 0.36; 'explain': 0.36; 'properties': 0.36; 'question': 0.36; 'uses': 0.36; 'bound': 0.37; 'things,': 0.37; 'skip:" 10': 0.37; 'but': 0.37; 'passed': 0.37; 'could': 0.37; 'using': 0.38; 'some': 0.38; 'couple': 0.38; 'created': 0.38; 'skip:o 20': 0.38; 'returned': 0.39; 'url:docs': 0.39; "i'd": 0.39; 'url:org': 0.39; 'should': 0.39; 'called': 0.40; "it's": 0.40; 'content-type:multipart/mixed': 0.60; 'type': 0.61; '2011': 0.61; 'types': 0.61; 'kind': 0.61; 'happen': 0.61; 'you.': 0.63; 'act': 0.65; 'below.': 0.66; '26,': 0.67; 'special': 0.68; 'safe': 0.70; 'fredrik': 0.84; 'hood': 0.84; 'lookup,': 0.84; 'mistakenly': 0.84; 'url:datamodel': 0.84; 'url:reference': 0.84 Date: Tue, 27 Dec 2011 19:05:04 +0100 (CET) From: Fredrik Tolf To: Ian Kelly Subject: Re: confused about __new__ In-Reply-To: References: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="-1463778303-1339839823-1325009105=:4050" X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.3.7 (nerv.dolda2000.com [IPv6:2002:54d9:e3a5:200::1]); Tue, 27 Dec 2011 19:05:05 +0100 (CET) Cc: python-list@python.org X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 85 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1325009109 news.xs4all.nl 6871 [2001:888:2000:d::a6]:37654 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:18037 This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---1463778303-1339839823-1325009105=:4050 Content-Type: TEXT/PLAIN; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8BIT On Tue, 27 Dec 2011, Ian Kelly wrote: > On Mon, Dec 26, 2011 at 10:48 PM, Fredrik Tolf wrote: >> I'm also a bit confused about __new__. I'd very much appreciate it if >> someone could explain the following aspects of it: >> >>  * The manual () says >>   that __new__ is "a static method (special-cased so you need not declare >>   it as such)". What does "special-cased" mean? Apparently, for >>   instance, in OP's case,  Python did not automatically detect that it >>   should not be bound as a method. > > It apparently has to do with the class creation. For the > special-casing to happen, the __new__ method has to be present when > the class is created. If it is, then it automatically gets wrapped in > a staticmethod. In the OP's case, he was adding the __new__ method > after class creation, so the wrapping did not happen automatically. Hmm, thank you. After trying a couple of things, it appears that the reason OP's method worked in Python 3 is that __get__ on ordinary functions in Python 3 simply returns the function itself when called on type lookup, rather than Python 2's unbound method objects. > http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy > """ > Class Types > Class types, or “new-style classes,” are callable. These objects > normally act as factories for new instances of themselves, but > variations are possible for class types that override __new__(). The > arguments of the call are passed to __new__() and, in the typical > case, to __init__() to initialize the new instance. > """ > > AFAIK, that's pretty much it. When a type is called, __new__ is > called to create the new instance, and then __init__ is called to > initialize it (if __new__ returned an instance of the type). Since that description doesn't include when __dict__ is created, it isn't complete, however. I guess it's safe to assume that __dict__ is created inside object.__new__, but that also leaves some things unclear; see below. >> how methods, properties and the like are bound; > > When they're accessed, using the descriptor protocol, not as part of > the instantiation process. See: > http://docs.python.org/reference/datamodel.html#invoking-descriptors Ah, sorry. I had read that, but I had mistakenly thought that the same instance method object was always returned, which would have implied that it had to be stored for the instance somewhere, at some point. I see now that that is not actually the case, however. That clears up a whole lot for me. Thanks! >> when and whether __dict__ >>   is created and a couple of other things. > > Under the hood as part of the object creation process, unless the > class uses __slots__. And also unless the object created is of type `object' or any other built-in type, which leaves me wondering exactly under what circumstances __dict__ actually is created. Is it some kind of special case in object.__new__ for types created with the `class' statement? There also appear to be other special cases in object.__new__: >>> object.__new__(dict) Traceback (most recent call last): File "", line 1, in TypeError: object.__new__(dict) is not safe, use dict.__new__() I guess my question reduces into the following: What does object.__new__ actually do, and what other special cases does it implement? -- Fredrik Tolf ---1463778303-1339839823-1325009105=:4050--