Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder1.enfer-du-nord.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!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; 'mess': 0.07; 'python': 0.08; '(there': 0.09; 'created,': 0.09; 'decorator': 0.09; 'imo.': 0.09; 'normally,': 0.09; 'url:activestate': 0.09; 'am,': 0.12; 'win32': 0.12; 'def': 0.13; 'classes,': 0.13; 'entries': 0.15; '"copyright",': 0.16; '"credits"': 0.16; '"license"': 0.16; 'arbitrarily,': 0.16; 'inherited': 0.16; 'instantiate': 0.16; 'metaclass': 0.16; 'normally.': 0.16; 'recognizing': 0.16; 'singleton': 0.16; 'subclasses,': 0.16; 'zero)': 0.16; '\xa0as': 0.16; '\xa0you': 0.16; 'cc:addr:python-list': 0.16; 'wrote:': 0.18; '>>>': 0.18; '3.2': 0.18; 'discard': 0.18; '(which': 0.19; 'cc:no real name:2**0': 0.20; 'dec': 0.22; '(or': 0.22; "doesn't": 0.22; 'feb': 0.22; 'header:In-Reply-To:1': 0.22; 'cc:2**0': 0.24; 'received:74.125.82.174': 0.24; 'modify': 0.25; 'code': 0.25; 'classes': 0.26; 'work,': 0.26; 'django': 0.26; 'raise': 0.28; 'url:code': 0.28; 'bit': 0.28; 'message-id:@mail.gmail.com': 0.28; '27,': 0.29; 'cc:addr:python.org': 0.29; 'class': 0.29; 'object.': 0.30; 'pattern': 0.30; '(e.g.': 0.31; 'does': 0.32; 'tue,': 0.32; 'actually': 0.33; 'rather': 0.33; 'there': 0.33; 'done': 0.34; 'it.': 0.34; 'normally': 0.34; 'richard': 0.34; 'things': 0.34; 'declared': 0.34; 'identical': 0.34; 'received:74.125.82': 0.35; 'url:python': 0.36; 'example,': 0.37; 'class.': 0.37; 'skip:" 10': 0.37; 'but': 0.37; 'received:74.125': 0.37; 'received:google.com': 0.37; 'options': 0.37; 'another': 0.37; 'think': 0.37; 'skip:_ 10': 0.37; 'could': 0.37; 'too,': 0.38; 'created': 0.38; 'client': 0.39; 'being': 0.39; "it's": 0.40; 'setup': 0.40; 'difference': 0.40; 'more': 0.61; 'type': 0.61; '2011': 0.61; 'matter': 0.61; 'collect': 0.61; 'create,': 0.63; 'results': 0.63; 'ever': 0.65; 'share': 0.66; 'conceptual': 0.67; 'url:it': 0.71; 'to:addr:rich': 0.84; "\xa0i'm": 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=LaMgxoC8qIpj3fvYsBB729R5NZdwW2UHPxr0/W8+o/o=; b=FIx50t0W6nVkGwBoEVyK9HELtS1lOYtkt7Jqhq7CGpBdRcM9HZLfCBQo0eUtCZV8Is Dk93lxtL5KqQFlk92EwvwRpzRgKutmisRPQ8BM2tiRUQq4ji9Y1BT8D9teNYAMXNCCiv OhdNJx+JDIatNW6xA600qx3fKHh2Mc8A7enfM= MIME-Version: 1.0 In-Reply-To: References: From: Ian Kelly Date: Tue, 27 Dec 2011 11:28:42 -0700 Subject: Re: confused about __new__ To: K Richard Pixley Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable 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: 56 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1325010560 news.xs4all.nl 6871 [2001:888:2000:d::a6]:51441 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:18043 On Tue, Dec 27, 2011 at 10:41 AM, K Richard Pixley wrote: > The conceptual leap for me was in recognizing that a class is just an > object. =A0The best way, (imo, so far), to create a singleton in python i= s to > use the class itself as the singleton rather than ever instantiating it. > =A0With a little work, you can even prevent it from ever being instantiat= ed. I don't think that's actually possible: Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> class Foo: ... def __new__(cls): ... raise TypeError ... def __init__(self): ... raise TypeError ... >>> type(object.__new__(Foo)) I prefer the Borg pattern for singletons myself. When you need a Borg instance, you just instantiate the class normally, do whatever you need with it, and then discard it normally. It doesn't matter how many instances there are (there can even be zero) because they all share identical state. It's better encapsulation too, since client code does not even need to know that the class is a singleton variant; that becomes an implementation detail. http://www.aleax.it/Python/5ep.html http://code.activestate.com/recipes/66531/ > But __metaclass__ could use a few more examples, imo. =A0I'm still not > entirely clear on __metaclass__. =A0As I understand it, (which may well b= e > completely wrong), __metaclass_ is the means of perturbing the results of > "isinstance". =A0You can create, (or delete), inheritance arbitrarily, an= d > without even requiring real, existing classes to do it. A metaclass is the class of another class (which is normally `type` if no metaclass is specified). It's used to customize the way that the class is created, in the same way that the class can be used to customize the way instances are created (e.g. by overriding __new__). You could use it to mess with the class's base classes, although I think that usage is rare. It's more common to use it to automatically add or modify entries in the class dict. For example, Django models use a metaclass to collect all the fields and options declared for the model class and to setup a default manager for the model class. Note that many things that can be done with a metaclass can also be done with a class decorator. The main difference as I see it is that the metaclass is inherited by subclasses, whereas a decorator would need to be applied individually to each subclass.