Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!feeds.phibee-telecom.net!newsfeed.xs4all.nl!newsfeed4.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; 'class,': 0.07; '__init__': 0.09; 'attributes': 0.09; 'code"': 0.09; 'latter': 0.09; 'lawrence': 0.09; 'cc:addr:python-list': 0.11; 'def': 0.12; 'language.': 0.14; '__new__': 0.16; 'arg):': 0.16; 'called,': 0.16; 'fiddle': 0.16; 'fits': 0.16; 'foo()': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'invariants.': 0.16; 'layout,': 0.16; 'necessary;': 0.16; 'other,': 0.16; 'rarely': 0.16; 'tuple': 0.16; 'sat,': 0.16; 'do,': 0.16; 'wrote:': 0.18; 'else,': 0.19; 'first.': 0.19; 'written': 0.21; 'feb': 0.22; 'cc:addr:python.org': 0.22; "shouldn't": 0.24; 'typical': 0.24; 'fairly': 0.24; 'cc:2**0': 0.24; 'this:': 0.26; 'header:In-Reply-To:1': 0.27; 'am,': 0.29; 'message-id:@mail.gmail.com': 0.30; 'accidentally': 0.31; 'safely': 0.31; "they'll": 0.31; 'class': 0.32; '"the': 0.34; 'skip:_ 10': 0.34; 'subject:the': 0.34; "can't": 0.35; 'anywhere': 0.35; 'common': 0.35; 'something': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'add': 0.35; 'should': 0.36; 'needed': 0.38; 'whatever': 0.38; 'anything': 0.39; 'called': 0.40; 'most': 0.60; 'guarantee': 0.63; 'situation': 0.65; 'obvious': 0.74; 'to:none': 0.92; 'anywhere,': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=41/b4yg6Mje0HlO9KWDNmo0obgANHmFrkvZA5Fz035A=; b=MfVmAdI4GHfRdEN5jamyjLUB7twbXX1pIfSFghEcPa6uJdMza2Gku8eXAC7rgss54z i+1YVtwuihTfds9HMme6uMf1q20RYJntZYFlgzwKqFYuWahXpVQ0Fe8t4zGhV6LLQYWK qVH5NV2ogU4iRYXXF9tf6q+trcQV1NJo0frTvkeENETDoCxQY4SzHBCmvXrZlzJaJhD7 e5ro71Fd/u6lvrhOpt4TkZAo5aHfQWyyBEx5N4/cqH3u8g3tSGO3eXQCFYYbwswWiQJg IywcFD7a5b/5YK/SfuJs75ZZvvdfoxe0Fsg1kxkbBczn/otyiizJKMtKmcw0JcG4GWYO ZPkg== MIME-Version: 1.0 X-Received: by 10.68.182.165 with SMTP id ef5mr3450164pbc.169.1391200108285; Fri, 31 Jan 2014 12:28:28 -0800 (PST) In-Reply-To: References: Date: Sat, 1 Feb 2014 07:28:28 +1100 Subject: Re: __init__ is the initialiser From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 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: 42 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1391200111 news.xs4all.nl 2912 [2001:888:2000:d::a6]:47362 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:65139 On Sat, Feb 1, 2014 at 7:17 AM, Mark Lawrence wrote: > To clarify the situation I think we should call __new__ "the thing that > instanciates an instance of a class" and __init__ "the thing that isn't > actually needed as you can add attributes to an instance anywhere in your > code" :) With a typical class layout, you have something like this: class Foo: def __init__(self, some, other, args): self.stuff=some+other, other+args def roll(self, arg): ret,keep=self.stuff self.stuff=keep,arg return ret This has an invariant: it always has a two-item tuple in self.stuff. The job of __init__ is to get the class invariants straight. Before it's called, you can't safely call anything else, because all those other parts of the class are written on the assumption that __init__ will be called first. This is a fairly common way of laying out a class, and it fits pretty much any language. So what is __new__ and what is __init__? The former is the thing you rarely need, and when you do, you can go fiddle with the docs if necessary; the latter is the most obvious place to guarantee invariants. Whatever you call them, they'll both be called before pretty much anything else in the class is, barring weirdnesses, which is something you cannot depend on with other methods. Yes, you can add attributes anywhere, but you shouldn't need this: f = Foo() f.setup(12,23,34) Instead, use this: f = Foo(12,23,34) And then there's no way to accidentally muck something up and have a Foo that breaks its invariants. ChrisA