Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #96305 > unrolled thread
| Started by | tdev@freenet.de |
|---|---|
| First post | 2015-09-10 15:25 -0700 |
| Last post | 2015-09-12 03:27 +0100 |
| Articles | 20 on this page of 27 — 10 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Python handles globals badly. tdev@freenet.de - 2015-09-10 15:25 -0700
Re: Python handles globals badly. Emile van Sebille <emile@fenx.com> - 2015-09-10 15:40 -0700
Re: Python handles globals badly. Ian Kelly <ian.g.kelly@gmail.com> - 2015-09-10 18:35 -0600
Re: Python handles globals badly. Marko Rauhamaa <marko@pacujo.net> - 2015-09-11 07:34 +0300
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-11 14:59 +1000
Re: Python handles globals badly. Marko Rauhamaa <marko@pacujo.net> - 2015-09-11 08:15 +0300
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-11 15:25 +1000
Re: Python handles globals badly. Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-09-12 03:43 +0100
Re: Python handles globals badly. Ian Kelly <ian.g.kelly@gmail.com> - 2015-09-10 23:07 -0600
Re: Python handles globals badly. Marko Rauhamaa <marko@pacujo.net> - 2015-09-11 08:27 +0300
Re: Python handles globals badly. Rustom Mody <rustompmody@gmail.com> - 2015-09-11 00:39 -0700
Re: Python handles globals badly. Steven D'Aprano <steve@pearwood.info> - 2015-09-11 18:42 +1000
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-11 19:16 +1000
Re: Python handles globals badly. Ian Kelly <ian.g.kelly@gmail.com> - 2015-09-11 09:03 -0600
Re: Python handles globals badly. Steven D'Aprano <steve@pearwood.info> - 2015-09-12 17:00 +1000
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-12 01:15 +1000
Re: Python handles globals badly. Ian Kelly <ian.g.kelly@gmail.com> - 2015-09-11 09:27 -0600
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-12 01:44 +1000
Re: Python handles globals badly. Ian Kelly <ian.g.kelly@gmail.com> - 2015-09-11 09:49 -0600
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-12 01:55 +1000
Re: Python handles globals badly. random832@fastmail.us - 2015-09-11 11:57 -0400
Re: Python handles globals badly. Rustom Mody <rustompmody@gmail.com> - 2015-09-11 09:08 -0700
Re: Python handles globals badly. Chris Angelico <rosuav@gmail.com> - 2015-09-12 02:04 +1000
Re: Python handles globals badly. Ian Kelly <ian.g.kelly@gmail.com> - 2015-09-11 10:27 -0600
Re: Python handles globals badly. Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-09-12 03:51 +0100
Re: Python handles globals badly. MRAB <python@mrabarnett.plus.com> - 2015-09-11 02:17 +0100
Re: Python handles globals badly. Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-09-12 03:27 +0100
Page 1 of 2 [1] 2 Next page →
| From | tdev@freenet.de |
|---|---|
| Date | 2015-09-10 15:25 -0700 |
| Subject | Re: Python handles globals badly. |
| Message-ID | <cd7b7ffa-a217-4b62-bad2-9095b33a2bb6@googlegroups.com> |
Some notes to the "global"-keyword and the other proposals. It has been proposed to have these six enhancements 1. optional keyword "global" 2. switch statement 3. less restrictive indentation 4. universal scope 5. goto label 6- "include" script statement with following proofs uncommented: Each sample provided would work without global (or you get runtime failure while try to write a global). So the compiler knows the distiction between global and local already. Otherwise you would have to write in every function this keyword But this is not the case. You write it because you need write access. And this is an over-regulation. So, NO need for an explicit global. Optional ok. Another proof about identation: The parser can recognise identation with tabs and spaces. Otherwise semcicolons or brackets would be needed. It is correct that there have to be a decision for spaces or tabs. But sure not necessarily the exact same indentation to the right for each block. Jus more same inserter to the right and the context is clear. Another proof is Python itself (from Tutorial): "Python is an ... powerful programming language. It has ... and a simple but effective approach to object-oriented programming. Python's elegant syntax ... together with its interpreted nature, make it an ideal language for scripting ... . The proposals are all made for structual programming enhancements This is nothing else than having structural programming, functional programming and OO and many more features in parallel. Why that all? For the same reason: For an another type of programmers - or say: nothing more than even more flexibility. Read also here: https://en.wikipedia.org/wiki/History_of_Python Especially sections: "incfluences from other languages" But all proposals are more or less fully denied - for more or less no reasons. The last statement against the proposals: > "EVERYONE who suggests massive, sweeping changes says "hey, if you only > make these changes, Python will actually become popular". It's almost > mandatory." Additionally, that proofs: that this is not a single meaning. And also speaking from changes is wrong. Enhancements or extensions would be correct. There is the big question: Who is responding or has responded? Extreme Programmers, Python-Hardliner, Python-Evangelists, ... . Presumably no core Python Programmers (wrting compiler and standard library stuff) On Google groups you can currently read for this thread: 37 Authors. 152 posts. 443 views. That is not that much for views (probably mostly from the writer's itself) So, is this really the place where a PEP can be started? When has a proposal to be accepted? If ten-thousands say yes? Which ten-thousands? Who decides it? Thanks.
[toc] | [next] | [standalone]
| From | Emile van Sebille <emile@fenx.com> |
|---|---|
| Date | 2015-09-10 15:40 -0700 |
| Message-ID | <mailman.342.1441924847.8327.python-list@python.org> |
| In reply to | #96305 |
On 9/10/2015 3:25 PM, tdev@freenet.de wrote: > Who decides it? The BDFL or his delegate. It's simplest that way. Emile
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-09-10 18:35 -0600 |
| Message-ID | <mailman.344.1441931751.8327.python-list@python.org> |
| In reply to | #96305 |
On Thu, Sep 10, 2015 at 4:25 PM, <tdev@freenet.de> wrote: > with following proofs uncommented: None of these are "proofs". > Each sample provided would work without global > (or you get runtime failure while try to write a global). What samples? It would be easier to follow your messages if you would include quotes from previous messages as context. > So the compiler knows the distiction between global and local already. As we've said before, it doesn't. The compiler's current rules are fairly simple: 1) If it's in the function's argument list, it's an argument (and therefore local). 2) If it's explicitly declared global, then it's global. 3) If it's never assigned within the function, then it's global. 4) Otherwise, it's local. If you take out step 2, then the compiler has no way of distinguishing whether a variable that is assigned to is local or global. > Another proof about identation: > The parser can recognise identation with tabs and spaces. You can use tabs *or* spaces. If you want to mix the two, then there would need to be some official decision made about how many spaces compose a tab, and then everybody who wants to use tabs would have to configure their editors to conform to that decision, or risk breaking their code. Some people like to indent two spaces. Some people like to indent four spaces. On the other hand, the de facto standard for terminal tab width is eight spaces. However, virtually nobody prefers eight spaces of indentation. So the question is which standard are you going to adopt, and which groups are you going to upset? I really doubt that you're going to gain any traction with this one, because the decision that was made with Python 3 was to make the compiler *more* rigid about not mixing tabs and spaces, not less. > It is correct that there have to be a decision for spaces or tabs. > But sure not necessarily the exact same indentation to the right for each block. > Jus more same inserter to the right and the context is clear. I don't understand what you're trying to say here. > But all proposals are more or less fully denied - for more or less no reasons. You've been given reasons. You seem unwilling to accept them. > There is the big question: > > Who is responding or has responded? > Extreme Programmers, Python-Hardliner, Python-Evangelists, ... . > Presumably no core Python Programmers (wrting compiler and standard library stuff) Ad hominem. > On Google groups you can currently read for this thread: > 37 Authors. 152 posts. 443 views. > > That is not that much for views (probably mostly from the writer's itself) This is not a Google Group. This is the comp.lang.python newsgroup, which is mirrored bidirectionally to the python.org python-list mailing list. Google Groups provides another portal to the newsgroup. There is no way to measure how many users have been reading this thread in the newsgroup or the mailing list. > So, is this really the place where a PEP can be started? No, this list is for general Python discussion. The place to present a PEP is the python-dev mailing list. It is generally considered advisable to post the idea to the python-ideas mailing list first, to find support for the idea and to hone it before going to the trouble of writing a PEP. If you do get to the point of writing a PEP, you will also need to have a clear picture of how you plan to actually implement the idea. It's not enough to just propose that "the global keyword should be optional". Precisely how would scopes be determined? How would you ensure backward compatibility? These are questions that would need answers before anything could be implemented. > When has a proposal to be accepted? If ten-thousands say yes? > Which ten-thousands? Who decides it? That's up to the BDFL.
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-09-11 07:34 +0300 |
| Message-ID | <87h9n1o9q4.fsf@elektro.pacujo.net> |
| In reply to | #96308 |
Ian Kelly <ian.g.kelly@gmail.com>: > You can use tabs *or* spaces. If you want to mix the two, then there > would need to be some official decision made about how many spaces > compose a tab, and then everybody who wants to use tabs would have to > configure their editors to conform to that decision, or risk breaking > their code. Some people like to indent two spaces. Some people like to > indent four spaces. On the other hand, the de facto standard for > terminal tab width is eight spaces. However, virtually nobody prefers > eight spaces of indentation. So the question is which standard are you > going to adopt, and which groups are you going to upset? Indentation preferences and the interpretation of TABs are two separate things. For example, in the default emacs configuration, the C indentation levels go like this: SPC SPC SPC SPC SPC SPC SPC SPC SPC SPC SPC SPC TAB TAB SPC SPC etc. The TAB *key* is a command that makes emacs indent with a mix of spaces and TABs. Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-11 14:59 +1000 |
| Message-ID | <mailman.353.1441947579.8327.python-list@python.org> |
| In reply to | #96318 |
On Fri, Sep 11, 2015 at 2:34 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > etc. The TAB *key* is a command that makes emacs indent with a mix of > spaces and TABs. I don't care how you key them in. If your tab key moves you to the next position, that's good. If you convert a sequence of N spaces into a tab character, though, that's bad, because then your file ends up with a mix, and an inconsistent one. To make emacs safe for use with Python code, you'll need to reconfigure it so the tab key inserts either a tab character or spaces, but never switches between them. Personally, I like to use tab characters for indentation. You can choose how many pixels or ems or ens or spaces the actual visual shift is, and if I disagree with your choice, it won't affect anything. As long as tabs are used _exclusively_, Python won't be bothered by it either. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-09-11 08:15 +0300 |
| Message-ID | <878u8do7u2.fsf@elektro.pacujo.net> |
| In reply to | #96319 |
Chris Angelico <rosuav@gmail.com>: > Personally, I like to use tab characters for indentation. You can > choose how many pixels or ems or ens or spaces the actual visual shift > is, and if I disagree with your choice, it won't affect anything. As > long as tabs are used _exclusively_, Python won't be bothered by it > either. Your preferred, novel usage of TABs, which runs counter to the age-old programming convention, has won enough supporters to make TABs unusable. No harm done. TABs have been banished. They were a bad idea in the first place. Marko
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-11 15:25 +1000 |
| Message-ID | <mailman.355.1441949149.8327.python-list@python.org> |
| In reply to | #96321 |
On Fri, Sep 11, 2015 at 3:15 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > Chris Angelico <rosuav@gmail.com>: > >> Personally, I like to use tab characters for indentation. You can >> choose how many pixels or ems or ens or spaces the actual visual shift >> is, and if I disagree with your choice, it won't affect anything. As >> long as tabs are used _exclusively_, Python won't be bothered by it >> either. > > Your preferred, novel usage of TABs, which runs counter to the age-old > programming convention, has won enough supporters to make TABs unusable. > > No harm done. TABs have been banished. They were a bad idea in the first > place. I don't understand. How does that usage run counter to the old conventions? A tab character, a press of the tab key, was a signal to move to the next logical column - regardless of the exact width of a column. It's also completely compatible with the stricter rule "a tab is equivalent to eight spaces". ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-09-12 03:43 +0100 |
| Message-ID | <mailman.391.1442025833.8327.python-list@python.org> |
| In reply to | #96321 |
On 11/09/2015 06:15, Marko Rauhamaa wrote: > Chris Angelico <rosuav@gmail.com>: > >> Personally, I like to use tab characters for indentation. You can >> choose how many pixels or ems or ens or spaces the actual visual shift >> is, and if I disagree with your choice, it won't affect anything. As >> long as tabs are used _exclusively_, Python won't be bothered by it >> either. > > Your preferred, novel usage of TABs, which runs counter to the age-old > programming convention, has won enough supporters to make TABs unusable. > > No harm done. TABs have been banished. They were a bad idea in the first > place. > > Marko > TABs might have been banished from some places, but certainly not Python. Of course you have to be careful or you run into problems with this:- TabError - Raised when indentation contains an inconsistent use of tabs and spaces. https://docs.python.org/3/library/exceptions.html#TabError -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-09-10 23:07 -0600 |
| Message-ID | <mailman.354.1441948080.8327.python-list@python.org> |
| In reply to | #96318 |
On Thu, Sep 10, 2015 at 10:34 PM, Marko Rauhamaa <marko@pacujo.net> wrote: > Ian Kelly <ian.g.kelly@gmail.com>: > >> You can use tabs *or* spaces. If you want to mix the two, then there >> would need to be some official decision made about how many spaces >> compose a tab, and then everybody who wants to use tabs would have to >> configure their editors to conform to that decision, or risk breaking >> their code. Some people like to indent two spaces. Some people like to >> indent four spaces. On the other hand, the de facto standard for >> terminal tab width is eight spaces. However, virtually nobody prefers >> eight spaces of indentation. So the question is which standard are you >> going to adopt, and which groups are you going to upset? > > Indentation preferences and the interpretation of TABs are two separate > things. > > For example, in the default emacs configuration, the C indentation > levels go like this: > > SPC SPC > SPC SPC SPC SPC > SPC SPC SPC SPC SPC SPC > TAB > TAB SPC SPC > > etc. The TAB *key* is a command that makes emacs indent with a mix of > spaces and TABs. That's all true but is tangential to my point. Emacs users with that setup would probably want the Python compiler to interpret a tab as eight spaces. On the other hand, the major benefit that is often touted for indentation using tab characters is that the reader can set their tab width and read the code with their preferred indentation (this fails however when using mixed tabs and spaces as in that Emacs scheme). Such users typically use one tab character as one level of indentation and would presumably prefer to have those tab characters interpreted as two or four spaces, not eight. If we're forced to choose a canonical tab width, both groups can't win. (Of course that Emacs indentation scheme already doesn't work for Python, but then the only possible benefit I can see to using it is a mild compression of the source code, an economy of disk space that really isn't necessary in this day and age.)
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-09-11 08:27 +0300 |
| Message-ID | <874mj1o78s.fsf@elektro.pacujo.net> |
| In reply to | #96320 |
Ian Kelly <ian.g.kelly@gmail.com>: > Emacs users with that setup would probably want the Python compiler to > interpret a tab as eight spaces. Which it does: Tabs are replaced (from left to right) by one to eight spaces such that the total number of characters up to and including the replacement is a multiple of eight (this is intended to be the same rule as used by Unix). <URL: https://docs.python.org/3/reference/lexical_analysis.html#lin e-structure> although that definition has been rendered insignificant in Python 3 by the footnote: Indentation is rejected as inconsistent if a source file mixes tabs and spaces in a way that makes the meaning dependent on the worth of a tab in spaces; a TabError is raised in that case. > On the other hand, the major benefit that is often touted for > indentation using tab characters is that the reader can set their tab > width and read the code with their preferred indentation (this fails > however when using mixed tabs and spaces as in that Emacs scheme). > Such users typically use one tab character as one level of indentation > and would presumably prefer to have those tab characters interpreted > as two or four spaces, not eight. That "innovation" has destroyed the TAB character. It won't be missed, though. > If we're forced to choose a canonical tab width, both groups can't > win. (Of course that Emacs indentation scheme already doesn't work for > Python, but then the only possible benefit I can see to using it is a > mild compression of the source code, an economy of disk space that > really isn't necessary in this day and age.) Emacs didn't invent that scheme. That's how TABs worked in my childhood across operating systems. However, TABs were always problematic for other reasons. If you added a space to the beginning of every line to shift everything to the right, TABs caused a misalignment. Marko
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-09-11 00:39 -0700 |
| Message-ID | <452038d3-cdcb-4786-b4e0-45df34c56ab8@googlegroups.com> |
| In reply to | #96318 |
On Friday, September 11, 2015 at 10:04:25 AM UTC+5:30, Marko Rauhamaa wrote: > Ian Kelly : > > > You can use tabs *or* spaces. If you want to mix the two, then there > > would need to be some official decision made about how many spaces > > compose a tab, and then everybody who wants to use tabs would have to > > configure their editors to conform to that decision, or risk breaking > > their code. Some people like to indent two spaces. Some people like to > > indent four spaces. On the other hand, the de facto standard for > > terminal tab width is eight spaces. However, virtually nobody prefers > > eight spaces of indentation. So the question is which standard are you > > going to adopt, and which groups are you going to upset? > > Indentation preferences and the interpretation of TABs are two separate > things. Required reading http://www.jwz.org/doc/tabs-vs-spaces.html
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-09-11 18:42 +1000 |
| Message-ID | <55f293da$0$1640$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #96308 |
On Fri, 11 Sep 2015 10:35 am, Ian Kelly wrote:
> On Thu, Sep 10, 2015 at 4:25 PM, <tdev@freenet.de> wrote:
[...]
>> So the compiler knows the distiction between global and local already.
>
> As we've said before, it doesn't. The compiler's current rules are
> fairly simple:
>
> 1) If it's in the function's argument list, it's an argument (and
> therefore local).
> 2) If it's explicitly declared global, then it's global.
> 3) If it's never assigned within the function, then it's global.
Almost. If it's never assigned within the function, then it is looked up
according to the non-local scoping rules:
- closures and enclosing functions (if any);
- globals;
- builtins;
in that order.
> 4) Otherwise, it's local.
"Otherwise" meaning "if it is assigned to", except that "del" counts as an
assignment. That is:
def spam():
del x
makes x a local variable inside the function spam.
There's also a bunch of specialised and complicated rules for what happens
if you make a star import ("from module import *") inside a function, or
call eval or exec without specifying a namespace. Both of these things are
now illegal in Python 3.
And lastly, in Python 3 only, there is also a nonlocal declaration which
works like global except it applies only to closures and enclosing
functions.
>> Another proof about identation:
>> The parser can recognise identation with tabs and spaces.
>
> You can use tabs *or* spaces.
In Python 3.
In Python 2, you can mix tabs *and* spaces, and Python will try to guess
what you mean. This causes more trouble than it is worth, and is removed in
Python 3.
[...]
> I really doubt that you're going to gain any traction with this one,
> because the decision that was made with Python 3 was to make the
> compiler *more* rigid about not mixing tabs and spaces, not less.
Correct.
[...]
>> Who is responding or has responded?
>> Extreme Programmers, Python-Hardliner, Python-Evangelists, ... .
>> Presumably no core Python Programmers (wrting compiler and standard
>> library stuff)
>
> Ad hominem.
For the record, I am the author of the statistics module in Python 3.4, and
Terry Reedy is the very active maintainer of IDLE. If I have missed anyone,
my apologies. So, yes, there are core developers here.
(Although not any of the senior core devs, as far as I know.)
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-11 19:16 +1000 |
| Message-ID | <mailman.364.1441962969.8327.python-list@python.org> |
| In reply to | #96333 |
On Fri, Sep 11, 2015 at 6:42 PM, Steven D'Aprano <steve@pearwood.info> wrote: >>> Who is responding or has responded? >>> Extreme Programmers, Python-Hardliner, Python-Evangelists, ... . >>> Presumably no core Python Programmers (wrting compiler and standard >>> library stuff) >> >> Ad hominem. > > For the record, I am the author of the statistics module in Python 3.4, and > Terry Reedy is the very active maintainer of IDLE. If I have missed anyone, > my apologies. So, yes, there are core developers here. > > (Although not any of the senior core devs, as far as I know.) I don't know what the definition of "senior core dev" would be. Checking the Experts List [1] shows you and Terry both, as does the list of committers [2] (and it has me as well, although that's because I wear a PEP Editor hat, so I don't count as even a non-senior core dev). Is there an "inner circle" of people Guido trusts more than "just ordinary core devs"? I rather suspect not, but maybe I'm wrong. Hacking on CPython without core dev status is actually pretty easy. I've done it. (Added a "while ... as name:" syntax, just to see how hard it would be. Conclusion: It's not hard at all.) If anything, that's a _lower_ bar to clear than "idiomatic Python programmer", because anyone can hack on C code without understanding the goals and beauties of the Python language. So I'm really not sure what the original complaint was about, nor how to answer it. ChrisA [1] https://docs.python.org/devguide/experts.html#experts [2] https://hg.python.org/committers.txt
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-09-11 09:03 -0600 |
| Message-ID | <mailman.370.1441983869.8327.python-list@python.org> |
| In reply to | #96333 |
On Fri, Sep 11, 2015 at 2:42 AM, Steven D'Aprano <steve@pearwood.info> wrote:
> On Fri, 11 Sep 2015 10:35 am, Ian Kelly wrote:
>
>> On Thu, Sep 10, 2015 at 4:25 PM, <tdev@freenet.de> wrote:
> [...]
>>> So the compiler knows the distiction between global and local already.
>>
>> As we've said before, it doesn't. The compiler's current rules are
>> fairly simple:
>>
>> 1) If it's in the function's argument list, it's an argument (and
>> therefore local).
>> 2) If it's explicitly declared global, then it's global.
>> 3) If it's never assigned within the function, then it's global.
>
> Almost. If it's never assigned within the function, then it is looked up
> according to the non-local scoping rules:
>
> - closures and enclosing functions (if any);
> - globals;
> - builtins;
>
> in that order.
I excluded non-locals intentionally, but if you want to be pedantic
about it, then that's still not quite right. Non-locals are indeed
identified by the compiler and compiled with the
LOAD_DEREF/STORE_DEREF opcodes (rather than the _GLOBAL and _FAST
variants used by globals and locals, respectively). The compiler
doesn't make any such distinction between globals and builtins
however, as that can only be determined at run-time.
> There's also a bunch of specialised and complicated rules for what happens
> if you make a star import ("from module import *") inside a function, or
> call eval or exec without specifying a namespace. Both of these things are
> now illegal in Python 3.
Huh?
>>> exec("x = 42")
>>> x
42
>>> exec("x = 43", None, None)
>>> x
43
That's in Python 3.4.0. Maybe I don't understand what you mean by
"without specifying a namespace".
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2015-09-12 17:00 +1000 |
| Message-ID | <55f3cd96$0$1655$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #96345 |
On Sat, 12 Sep 2015 01:03 am, Ian Kelly wrote:
> On Fri, Sep 11, 2015 at 2:42 AM, Steven D'Aprano <steve@pearwood.info>
> wrote:
[...]
>> Almost. If it's never assigned within the function, then it is looked up
>> according to the non-local scoping rules:
>>
>> - closures and enclosing functions (if any);
>> - globals;
>> - builtins;
>>
>> in that order.
>
> I excluded non-locals intentionally, but if you want to be pedantic
> about it, then that's still not quite right. Non-locals are indeed
> identified by the compiler and compiled with the
> LOAD_DEREF/STORE_DEREF opcodes (rather than the _GLOBAL and _FAST
> variants used by globals and locals, respectively).
Ah, nice, yes I forgot about that, thanks for the correction.
> The compiler
> doesn't make any such distinction between globals and builtins
> however, as that can only be determined at run-time.
>
>> There's also a bunch of specialised and complicated rules for what
>> happens if you make a star import ("from module import *") inside a
>> function, or call eval or exec without specifying a namespace. Both of
>> these things are now illegal in Python 3.
>
> Huh?
>
>>>> exec("x = 42")
>>>> x
> 42
>>>> exec("x = 43", None, None)
>>>> x
> 43
>
> That's in Python 3.4.0. Maybe I don't understand what you mean by
> "without specifying a namespace".
Inside a function star imports are illegal in Python 3:
py> def f():
... from math import *
...
File "<stdin>", line 1
SyntaxError: import * only allowed at module level
My recollection was incorrect about exec. You can still exec inside a
function, but it may have no effect:
py> def f():
... x = 1
... exec("x = 2")
... return x
...
py> f()
1
You can specify locals, but it doesn't help:
py> def f():
... x = 1
... exec("x = 2", globals(), locals())
... return x
...
py> f()
1
However, in Python 2, Python tried hard to make exec work:
py> def f():
... x = 1
... exec("x = 2")
... return x
...
py> f()
2
I don't recall all the details, but in Python 2 functions could use two
different schemes for local variables: the regular, optimized one using
memory slots, and a dict-based one that came into play with exec. So we
have this:
py> def g():
... a = 1
... exec("b = 2")
... return (a, b)
...
py> dis.dis(g)
2 0 LOAD_CONST 1 (1)
3 STORE_FAST 0 (a)
3 6 LOAD_CONST 2 ('b = 2')
9 LOAD_CONST 0 (None)
12 DUP_TOP
13 EXEC_STMT
4 14 LOAD_FAST 0 (a)
17 LOAD_NAME 0 (b)
20 BUILD_TUPLE 2
23 RETURN_VALUE
`a` is a regular, optimized local looked up with LOAD_FAST; but `b` gets the
same old LOAD_NAME used for globals and built-ins.
In Python 3.3, that same function uses LOAD_GLOBAL for `b`, even though the
variable does actually exist:
py> dis.dis(g)
2 0 LOAD_CONST 1 (1)
3 STORE_FAST 0 (a)
3 6 LOAD_GLOBAL 0 (exec)
9 LOAD_CONST 2 ('b = 2')
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
15 POP_TOP
4 16 LOAD_FAST 0 (a)
19 LOAD_GLOBAL 1 (b)
22 BUILD_TUPLE 2
25 RETURN_VALUE
py> g()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in g
NameError: global name 'b' is not defined
The conclusion I draw from all this is that the rules governing local
variables in Python are a mess :-)
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-12 01:15 +1000 |
| Message-ID | <mailman.371.1441984523.8327.python-list@python.org> |
| In reply to | #96333 |
On Sat, Sep 12, 2015 at 1:03 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>> There's also a bunch of specialised and complicated rules for what happens
>> if you make a star import ("from module import *") inside a function, or
>> call eval or exec without specifying a namespace. Both of these things are
>> now illegal in Python 3.
>
> Huh?
>
>>>> exec("x = 42")
>>>> x
> 42
>>>> exec("x = 43", None, None)
>>>> x
> 43
>
> That's in Python 3.4.0. Maybe I don't understand what you mean by
> "without specifying a namespace".
*inside a function*
>>> def f():
... exec("x = 42")
... print(x)
...
>>> x = 231
>>> f()
231
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-09-11 09:27 -0600 |
| Message-ID | <mailman.372.1441985273.8327.python-list@python.org> |
| In reply to | #96333 |
On Fri, Sep 11, 2015 at 9:15 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Sat, Sep 12, 2015 at 1:03 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>>> There's also a bunch of specialised and complicated rules for what happens
>>> if you make a star import ("from module import *") inside a function, or
>>> call eval or exec without specifying a namespace. Both of these things are
>>> now illegal in Python 3.
>>
>> Huh?
>>
>>>>> exec("x = 42")
>>>>> x
>> 42
>>>>> exec("x = 43", None, None)
>>>>> x
>> 43
>>
>> That's in Python 3.4.0. Maybe I don't understand what you mean by
>> "without specifying a namespace".
>
> *inside a function*
>
>>>> def f():
> ... exec("x = 42")
> ... print(x)
> ...
>>>> x = 231
>>>> f()
> 231
Ah, I didn't parse the "inside a function" as applying to that clause,
but even so, I don't see in what way that is "now illegal". For
example:
>>> x = 231
>>> def f():
... exec("print(x); x = 42; print(x)")
... print(x)
...
>>> f()
231
42
231
The exec still happily runs; it's just using its own private locals namespace.
Tangent: does the help for exec need to be updated? It currently reads:
The globals and locals are dictionaries, defaulting to the current
globals and locals. If only globals is given, locals defaults to it.
Which would seem to indicate that if called from within a function
with no globals or locals, the locals from the function would be used.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-12 01:44 +1000 |
| Message-ID | <mailman.373.1441986260.8327.python-list@python.org> |
| In reply to | #96333 |
On Sat, Sep 12, 2015 at 1:27 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> The exec still happily runs; it's just using its own private locals namespace.
>
> Tangent: does the help for exec need to be updated? It currently reads:
>
> The globals and locals are dictionaries, defaulting to the current
> globals and locals. If only globals is given, locals defaults to it.
>
> Which would seem to indicate that if called from within a function
> with no globals or locals, the locals from the function would be used.
And that's the thing... I think. It's using locals(), which starts out
as a copy of the function's locals (in this example, empty), but
without assignment affecting anything. Which is more than a little
weird:
>>> def f():
... x = [1]
... exec("print(x); x[0] = 2; print(x); x = [3]; print(x)")
... print(x)
...
>>> f()
[1]
[2]
[3]
[2]
It's kinda like how globals can shadow builtins, I think. Maybe.
Except that you can't del the name inside exec to unshadow and go back
to the outer version of it.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-09-11 09:49 -0600 |
| Message-ID | <mailman.374.1441986629.8327.python-list@python.org> |
| In reply to | #96333 |
On Fri, Sep 11, 2015 at 9:44 AM, Chris Angelico <rosuav@gmail.com> wrote:
> On Sat, Sep 12, 2015 at 1:27 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>> The exec still happily runs; it's just using its own private locals namespace.
>>
>> Tangent: does the help for exec need to be updated? It currently reads:
>>
>> The globals and locals are dictionaries, defaulting to the current
>> globals and locals. If only globals is given, locals defaults to it.
>>
>> Which would seem to indicate that if called from within a function
>> with no globals or locals, the locals from the function would be used.
>
> And that's the thing... I think. It's using locals(), which starts out
> as a copy of the function's locals (in this example, empty), but
> without assignment affecting anything. Which is more than a little
> weird:
>
>>>> def f():
> ... x = [1]
> ... exec("print(x); x[0] = 2; print(x); x = [3]; print(x)")
> ... print(x)
> ...
>>>> f()
> [1]
> [2]
> [3]
> [2]
Ah, that makes sense. It's writing into the dict that is created and
returned by locals(), but not actually updating the frame locals which
are the source of truth.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-12 01:55 +1000 |
| Message-ID | <mailman.375.1441986932.8327.python-list@python.org> |
| In reply to | #96333 |
On Sat, Sep 12, 2015 at 1:49 AM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
>> And that's the thing... I think. It's using locals(), which starts out
>> as a copy of the function's locals (in this example, empty), but
>> without assignment affecting anything. Which is more than a little
>> weird:
>>
>>>>> def f():
>> ... x = [1]
>> ... exec("print(x); x[0] = 2; print(x); x = [3]; print(x)")
>> ... print(x)
>> ...
>>>>> f()
>> [1]
>> [2]
>> [3]
>> [2]
>
> Ah, that makes sense. It's writing into the dict that is created and
> returned by locals(), but not actually updating the frame locals which
> are the source of truth.
Yeah... but it only makes sense to people who understand the
implementation. It's certainly not a logical and sane behaviour that
would be worth documenting and using.
ChrisA
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.python
csiph-web