Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.dougwise.org!nntpfeed.proxad.net!proxad.net!feeder1-1.proxad.net!feeder.news-service.com!newsfeed.xs4all.nl!newsfeed5.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; 'python,': 0.01; 'context': 0.04; 'sys': 0.05; 'subject:Python': 0.06; 'defaults': 0.07; 'rest,': 0.07; 'python': 0.08; '>>>>': 0.09; 'attribute.': 0.09; 'dict': 0.09; 'executed': 0.09; 'none.': 0.09; 'none:': 0.09; 'syntax.': 0.09; 'tuple': 0.09; 'variables.': 0.09; 'wrappers': 0.09; 'am,': 0.12; 'classes,': 0.13; 'def': 0.15; 'argument': 0.15; '"normal"': 0.16; "'',": 0.16; '(),': 0.16; 'behaviour,': 0.16; 'bindings': 0.16; 'class:': 0.16; 'code!': 0.16; 'container.': 0.16; 'discarded.': 0.16; 'executed.': 0.16; 'globals[,': 0.16; 'inherited': 0.16; 'len': 0.16; 'overrides': 0.16; 'simplest': 0.16; '{})': 0.16; 'cc:addr:python-list': 0.16; 'syntax': 0.16; 'wrote:': 0.16; 'functions,': 0.18; 'simpler': 0.18; 'specifies': 0.18; '(which': 0.19; 'cc:no real name:2**0': 0.20; 'cc:2**0': 0.22; 'header:In-Reply-To:1': 0.22; '(or': 0.23; 'frequent': 0.23; 'least,': 0.23; 'objects,': 0.23; 'optional': 0.23; 'values.': 0.23; 'aug': 0.24; 'object,': 0.24; 'code': 0.25; 'creating': 0.25; 'statement': 0.25; 'saying': 0.26; 'string': 0.26; 'code.': 0.26; 'function': 0.27; 'skip:[ 10': 0.27; 'code,': 0.28; 'classes': 0.28; 'url:mailman': 0.28; 'import': 0.28; 'accessible': 0.29; 'explicitly': 0.29; 'importing': 0.29; 'message-id:@mail.gmail.com': 0.29; 'specifically': 0.29; 'cc:addr:python.org': 0.30; 'module': 0.30; 'turned': 0.30; 'confident': 0.30; 'modules,': 0.30; 'object.': 0.30; 'objects.': 0.30; 'thanks': 0.30; 'class': 0.30; 'modules': 0.31; 'objects': 0.32; 'does': 0.32; 'source': 0.33; "isn't": 0.33; 'it.': 0.33; "can't": 0.33; 'there': 0.33; 'url:listinfo': 0.33; "i've": 0.34; 'however,': 0.34; 'be.': 0.34; 'eric': 0.34; 'file.': 0.34; 'sense,': 0.34; 'object': 0.35; 'unless': 0.36; 'url:python': 0.36; 'fri,': 0.36; 'but': 0.37; 'think': 0.38; 'steven': 0.38; 'some': 0.38; 'received:google.com': 0.38; 'url:org': 0.38; 'received:209.85': 0.38; 'subject:: ': 0.39; 'under': 0.39; 'itself.': 0.39; 'skip:\xa0 10': 0.39; 'enough': 0.39; 'empty': 0.39; 'case': 0.39; 'skip:d 20': 0.39; 'agreed': 0.40; 'where': 0.40; 'more': 0.60; 'your': 0.61; 'hope': 0.61; 'free': 0.63; 'believe': 0.65; 'taking': 0.66; 'received:209.85.215.174': 0.67; 'received:mail-ey0-f174.google.com': 0.67; 'special': 0.67; 'imagine': 0.71; 'container': 0.73; 'why?': 0.73; ':).': 0.84; 'machine,': 0.84; 'mechanics': 0.84; 'supplies': 0.84; 'alone,': 0.91; 'confusion.': 0.91; 'snow': 0.91; 'unclear': 0.91; 'look.': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=/04wvmzm5MOf+TuaXpJw/fGf8V2BOs6PkoT4EKkXkso=; b=VG83owqi5TjFsQbPWmEY85sJSimdQ/qxCcsT3m03fjjeCiljt8hTtbslryQWtxS0qf AKmv6XDg34/iVB7tKuVJoXD3ssTBZRzSm1gakLG2PjyId/fuMoDPoY8rbXAJmvSZQLV1 dCfV+tnY4wwN/iLFIU1MsI2cXxvcFBHaXaaTY= MIME-Version: 1.0 In-Reply-To: <4e3bffe1$0$29996$c3e8da3$5496439d@news.astraweb.com> References: <4e3bffe1$0$29996$c3e8da3$5496439d@news.astraweb.com> Date: Fri, 5 Aug 2011 10:46:02 -0600 Subject: Re: Observations on the three pillars of Python execution From: Eric Snow To: "Steven D'Aprano" 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: 114 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1312562764 news.xs4all.nl 23872 [2001:888:2000:d::a6]:34480 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:10913 On Fri, Aug 5, 2011 at 8:36 AM, Steven D'Aprano wrote: > Eric Snow wrote: > >> In Python, three types of objects have special syntax and mechanics >> for their instantiation, during which a code object is generated: >> modules, classes, and functions. > > I believe you are labouring under a misapprehension. Modules and classes > don't generate code objects. Sorry for any confusion. I was talking specifically about the their instantiation through their respective special syntax. During that process a code object is generated for each. For classes and modules the code object is executed and then discarded. I covered this explicitly in one of the observations. > > The simplest possible module just has a name: > >>>> import sys >>>> module =3D type(sys) >>>> module("name") > > > Or if you prefer to do it the "normal" way by importing from source code, > the simplest source code of all is just an empty file. > > A module is an object with a __dict__, a __name__, and a __docstring__ wh= ich > defaults to None. That's it. No code objects, unless you populate the > __dict__ with functions, but it is the *functions* that have the code > objects, not the module itself. The module is just a container. > > Classes are similar. The simplest class: > > class K: > =A0 =A0pass > > or if you prefer: > >>>> type('K', (), {}) > > > > Again, no code objects unless you populate the dict with functions (which > get turned into methods). Again, the class object is just a container. A > more complex container than modules, with a richer set of inherited > behaviour, but still just a container. > > The signature for creating a function is very different: > > help(type(lambda: None)) =3D> > > class function(object) > =A0| =A0function(code, globals[, name[, argdefs[, closure]]]) > =A0| > =A0| =A0Create a function object from a code object and a dictionary. > =A0| =A0The optional name string overrides the name from the code object. > =A0| =A0The optional argdefs tuple specifies the default argument values. > =A0| =A0The optional closure tuple supplies the bindings for free variabl= es. > > > The simplest function I can think of: > >>>> co =3D compile('pass', '', 'single') >>>> f =3D type(lambda: None)(co, {}) > > Even simpler than > > def f(): > =A0 =A0pass > > Can you see why? > > If you inspect a function object, you will see that it always has a code > object, even if the code object does nothing but return None: > >>>> import dis >>>> dis.dis(f.func_code) > =A01 =A0 =A0 =A0 =A0 =A0 0 LOAD_CONST =A0 =A0 =A0 =A0 =A0 =A0 =A0 0 (None= ) > =A0 =A0 =A0 =A0 =A0 =A0 =A03 RETURN_VALUE > > > There may be some other obscure built-in type that includes code objects, > but I can't imagine what it would be. I feel confident in saying that > functions, and functions alone, contain code. Even methods are just > wrappers around functions. Even built-in functions like len don't contain > code! (Or at least, their code isn't accessible from Python.) Which makes > sense, if you think about it: their code is part of the Python virtual > machine, not the object. Agreed that [non-builtin] functions are the only objects that have a code object attribute. However, they are not the only objects for which a code object is generated and executed. I've always found your frequent responses very insightful and thoughtful, Steven, and I appreciate that. In this case I can only imagine that my opening statement was unclear enough that you did not continue to read the rest, where the context of my point was more clear (I hope :). Regardless, thanks for taking a look. -eric > > > -- > Steven > > -- > http://mail.python.org/mailman/listinfo/python-list >