Quirk difference between classes and functions

jfong at ms4.hinet.net jfong at ms4.hinet.net
Tue Feb 26 22:58:14 EST 2019


Chris Angelico於 2019年2月27日星期三 UTC+8上午11時29分04秒寫道:
> On Wed, Feb 27, 2019 at 2:21 PM <jfong at ms4.hinet.net> wrote:
> >
> > Chris Angelico於 2019年2月27日星期三 UTC+8上午9時25分11秒寫道:
> > > On Wed, Feb 27, 2019 at 12:21 PM <jfong at ms4.hinet.net> wrote:
> > > >
> > > > Gregory Ewing at 2019/2/27 AM 5:26:49 wrote:
> > > > > Thomas Jollans wrote:
> > > > > > I imagine there's a justification for the difference in behaviour to do
> > > > > > with the fact that the body of a class is only ever executed once, while
> > > > > > the body of a function is executed multiple times.
> > > > >
> > > > > I suspect there isn't any deep reason for it, rather it's just
> > > > > something that fell out of the implementation, in particular
> > > > > the decision to optimise local variable access in functions
> > > > > but not other scopes.
> > > > >
> > > > > When compiling a function, the compiler needs to know which
> > > > > variables are local so that it can allocate slots for them in
> > > > > the stack frame. But when executing a class body, the locals
> > > > > are kept in a dict and are looked up dynamically.
> > > >
> > > > If the compiler can do any decision on the variable's name, when it goes to line of print, how it handle it?
> > > >
> > > > x = 0
> > > > def f():
> > > >     print(x)
> > > >
> > > > def g():
> > > >     print(x)
> > > >     x = 1
> > > >     print(y)
> > > >
> > >
> > > Not sure what you mean by "decision", but the definition is that since
> > > x is assigned to in g(), it is local to g(). It's not local to f(), so
> > > the global is visible.
> >
> > So, may I say that the Python compiler is a multi-pass one?
> >
> 
> At this point, you're veering away from "Python-the-language" and
> towards "CPython-the-implementation" (or whichever other
> implementation you want to explore). 

Yes, it's a little away:-) I was curious about how the compiled print(x) can be influenced by x = 1 after it. Anyway, thank you for your confirmation.

--Jach

> But I would say that, yes, most
> or all Python implementations will use multi-pass compilation. It's
> the easiest way to guarantee correct behaviour. For instance, when you
> reach a "try" statement, you don't know whether there'll be an
> "except" block after it (there might just be a "finally"); the
> bytecode that CPython produces is different for setting up a
> finally-only block than for setting up a try/except. Easiest to find
> out that sort of thing by running multiple passes.
> 
> Plus, depending on how you define "pass", there are additional steps
> such as constant folding and peephole optimization that can be done
> after everything else. So, yeah, it's highly unlikely that there are
> any performant implementations of Python that run a single compilation
> pass.
> 
> ChrisA



More information about the Python-list mailing list