Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.albasani.net!news.stack.nl!newsfeed.xs4all.nl!newsfeed1.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; 'that?': 0.05; 'initialize': 0.07; '__init__': 0.09; 'constructor': 0.09; 'created,': 0.09; 'method,': 0.09; 'methods,': 0.09; 'modulo': 0.09; 'objects,': 0.09; 'oop': 0.09; 'override': 0.09; 'thus,': 0.09; 'toolkit': 0.09; 'toss': 0.09; 'window.': 0.09; 'cc:addr :python-list': 0.11; 'gui': 0.12; 'language.': 0.14; '__new__': 0.16; 'cls': 0.16; 'constructs': 0.16; 'downside': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'object;': 0.16; 'stuff.': 0.16; 'sat,': 0.16; 'wrote:': 0.18; 'first.': 0.19; 'feb': 0.22; 'code,': 0.22; 'cc:addr:python.org': 0.22; 'button,': 0.24; 'documented': 0.24; 'oriented': 0.24; 'java': 0.24; 'cc:2**0': 0.24; "i've": 0.25; 'class.': 0.26; 'first,': 0.26; 'least': 0.26; 'header:In-Reply-To:1': 0.27; 'idea': 0.28; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; "d'aprano": 0.31; 'steven': 0.31; 'themselves': 0.32; 'entirely': 0.33; 'programmers': 0.33; '"the': 0.34; 'skip:_ 10': 0.34; 'maybe': 0.34; 'subject:the': 0.34; 'could': 0.34; 'but': 0.35; 'received:google.com': 0.35; 'really': 0.36; 'c++': 0.36; 'done': 0.36; 'should': 0.36; 'so,': 0.37; 'two': 0.37; 'being': 0.38; 'button': 0.38; 'whatever': 0.38; 'pm,': 0.38; 'expect': 0.39; 'does': 0.39; 'sure': 0.39; 'either': 0.39; 'how': 0.40; 'easy': 0.60; 'event.': 0.60; 'new': 0.61; 'between': 0.67; 'difficulty': 0.68; 'obvious': 0.74; 'etc,': 0.84; 'want:': 0.84; 'write:': 0.91; 'to:none': 0.92 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=HUUCtSaUrwH42yzjzV/ACXrppfjXos1OaDddu2RcF7I=; b=YN9CFhZEIgXSUsujCMndJPILCXlVU/2ty11U8awTjYZ3QeaStc5QBiqlxAbw6ZBNzC 2uGzY4/cEPAKIj2MGhcHvStXLmyxpf+sHE5YHUPmsqs2kuyCIFb6VUn6wlI4694Y6XU0 vMwJtQ5p1ZV3lIRKKuTUa+8W/AEu9Dre8z4vA4aHbHK6xAzEosjvXARF6fpHwdy5C9+0 6JaoXJufi9SSbfkYmJ00ESGX2akeOvIbstrvzwCF0AG+Iy3dFsleRmiNtAOO3rV4Nr7R JXYGdhqi7Hu+amCg/8+WYSp789nykfs2T5FCrR2vDwWccJ285YVGPwKZo11zaErGtarS ybRw== MIME-Version: 1.0 X-Received: by 10.67.22.100 with SMTP id hr4mr24543270pad.112.1391229317311; Fri, 31 Jan 2014 20:35:17 -0800 (PST) In-Reply-To: <52ec6d1f$0$29972$c3e8da3$5496439d@news.astraweb.com> References: <52ec6d1f$0$29972$c3e8da3$5496439d@news.astraweb.com> Date: Sat, 1 Feb 2014 15:35:17 +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: 56 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1391229320 news.xs4all.nl 2922 [2001:888:2000:d::a6]:59944 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:65181 On Sat, Feb 1, 2014 at 2:42 PM, Steven D'Aprano wrote: > I've met people who have difficulty with OOP principles, at least at > first. But once you understand the idea of objects, it isn't that hard to > understand the idea that: > > - first, the object has to be created, or constructed, or allocated > if you will; > > - only then can it be initialised. > > Thus, two methods. __new__ constructs (creates, allocates) a new object; > __init__ initialises it after the event. Yes, but if you think in terms of abstractions, they're both just steps in the conceptual process of "creating the object". If I ask GTK to create me a Button, I don't care how many steps it has to go through of allocating memory, allocating other resources, etc, etc, etc. All I want is to be able to write: foobar = Button("Foo Bar") and, at the end of it, to have a Button that I can toss onto a window. That's the job of a constructor - to give me an object in a state that I can depend on. (And this is completely independent of language. Modulo trivialities like semicolons, adorned names, etc, etc, I would expect that this be valid in any object oriented GUI toolkit in any object oriented language.) The difference between __new__ and __init__ is important when you write either method, but not when you use the class. It's like writing other dunder methods. You care about the distinction between __add__ and __radd__ when you write the methods, but in all other code, all that matters is that it does what you want: three = Three() four = three + 1 four == 1 + three The two methods could have been done as a single method, __construct__, in which you get passed a cls instead of a self, and you call self=super().__construct__() and then initialize stuff. It would then be obvious that this is "the constructor". So maybe it's best to talk about the two methods collectively as "the constructor", and then let people call the two parts whatever they will. I do like the idea of calling __init__ the initializer. The downside of calling __new__ the constructor is that it'll encourage C++ and Java programmers to override it and get themselves confused, when really they should have been writing __init__ and having an easy time of it. So, current best suggestion is "allocator" for that? Not entirely sure that's right, but it's not terrible. I'm +1 on __init__ being documented as the initializer, and +0 on "allocator" for __new__. ChrisA