Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #59142 > unrolled thread
| Started by | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| First post | 2013-11-11 18:06 -0800 |
| Last post | 2013-11-16 15:14 +1100 |
| Articles | 20 on this page of 52 — 17 participants |
Back to article view | Back to comp.lang.python
PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-11 18:06 -0800
Re: PyMyth: Global variables are evil... WRONG! Tim Daneliuk <tundra@tundraware.com> - 2013-11-11 20:47 -0600
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-11 20:46 -0800
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-12 16:02 +1100
Re: PyMyth: Global variables are evil... WRONG! Ricardo Aráoz <ricaraoz@gmail.com> - 2013-11-12 07:15 -0300
Re: PyMyth: Global variables are evil... WRONG! Tim Chase <python.list@tim.thechases.com> - 2013-11-12 05:32 -0600
Re: PyMyth: Global variables are evil... WRONG! Terry Reedy <tjreedy@udel.edu> - 2013-11-12 20:20 -0500
Re: PyMyth: Global variables are evil... WRONG! Tim Daneliuk <tundra@tundraware.com> - 2013-11-13 18:17 -0600
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 18:25 -0800
Re: PyMyth: Global variables are evil... WRONG! jongiddy <jongiddy@gmail.com> - 2013-11-12 06:12 -0800
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-12 07:05 -0800
Re: PyMyth: Global variables are evil... WRONG! jongiddy <jongiddy@gmail.com> - 2013-11-12 07:33 -0800
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-12 09:00 -0800
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-12 09:42 -0800
Re: PyMyth: Global variables are evil... WRONG! Tim Chase <python.list@tim.thechases.com> - 2013-11-12 11:45 -0600
Re: PyMyth: Global variables are evil... WRONG! jongiddy <jongiddy@gmail.com> - 2013-11-12 14:41 -0800
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-12 18:45 -0800
Re: PyMyth: Global variables are evil... WRONG! Tim Chase <python.list@tim.thechases.com> - 2013-11-12 21:22 -0600
Re: PyMyth: Global variables are evil... WRONG! Andrew Cooper <root@127.0.0.1> - 2013-11-13 22:00 +0000
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 18:16 -0800
Re: PyMyth: Global variables are evil... WRONG! Alister <alister.ware@ntlworld.com> - 2013-11-12 14:32 +0000
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-13 02:22 +1100
Re: PyMyth: Global variables are evil... WRONG! "Rhodri James" <rhodri@wildebst.demon.co.uk> - 2013-11-13 23:42 +0000
Re: PyMyth: Global variables are evil... WRONG! Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-11-13 23:57 +0000
Re: PyMyth: Global variables are evil... WRONG! Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-14 01:09 +0000
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 19:22 -0800
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-14 14:29 +1100
Re: PyMyth: Global variables are evil... WRONG! Roy Smith <roy@panix.com> - 2013-11-13 23:33 -0500
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 20:40 -0800
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-14 15:53 +1100
Re: PyMyth: Global variables are evil... WRONG! Steven D'Aprano <steve@pearwood.info> - 2013-11-14 06:25 +0000
Re: PyMyth: Global variables are evil... WRONG! unknown <unknown@unknown.com> - 2013-11-14 09:41 +0000
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 18:10 -0800
Re: PyMyth: Global variables are evil... WRONG! Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-14 02:45 +0000
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 19:45 -0800
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-13 20:01 -0800
Re: PyMyth: Global variables are evil... WRONG! Steven D'Aprano <steve@pearwood.info> - 2013-11-14 05:50 +0000
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-14 09:26 -0800
Re: PyMyth: Global variables are evil... WRONG! Joel Goldstick <joel.goldstick@gmail.com> - 2013-11-14 12:37 -0500
Re: PyMyth: Global variables are evil... WRONG! Ethan Furman <ethan@stoneleaf.us> - 2013-11-14 09:56 -0800
Re: PyMyth: Global variables are evil... WRONG! Alister <alister.ware@ntlworld.com> - 2013-11-14 20:12 +0000
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-15 09:43 +1100
Re: PyMyth: Global variables are evil... WRONG! Joel Goldstick <joel.goldstick@gmail.com> - 2013-11-14 13:43 -0500
Re: PyMyth: Global variables are evil... WRONG! Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-11-14 19:04 +0000
Re: PyMyth: Global variables are evil... WRONG! Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-11-15 08:19 +0000
Re: PyMyth: Global variables are evil... WRONG! Tim Daneliuk <tundra@tundraware.com> - 2013-11-15 09:26 -0600
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-16 02:42 +1100
Re: PyMyth: Global variables are evil... WRONG! Tim Daneliuk <tundra@tundraware.com> - 2013-11-15 17:33 -0600
Re: PyMyth: Global variables are evil... WRONG! Tim Daneliuk <tundra@tundraware.com> - 2013-11-15 17:33 -0600
Re: PyMyth: Global variables are evil... WRONG! Rick Johnson <rantingrickjohnson@gmail.com> - 2013-11-15 20:01 -0800
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-16 15:19 +1100
Re: PyMyth: Global variables are evil... WRONG! Chris Angelico <rosuav@gmail.com> - 2013-11-16 15:14 +1100
Page 1 of 3 [1] 2 3 Next page →
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-11 18:06 -0800 |
| Subject | PyMyth: Global variables are evil... WRONG! |
| Message-ID | <7b97786a-2aaf-454c-8c3a-1c19d20d4345@googlegroups.com> |
PyMyth: Global variables are evil... WRONG!
============================================================
Python's Global Hysteria:
============================================================
How many times have your heard or read the phrase: "Global
variables are evil"? Well if you've been a member of the
Python community, I'll bet you've heard or read it more than
most other community members.
In this thread, i want to get to the bottom of this whole
"global-phobia" thing once and for all, and hopefully help
you folks understand that globals are not all that bad --
when DESIGNED and USED correctly that is!
============================================================
The denial of the 99%:
============================================================
Python has globals, but we just can't admit it!
The creators thought they would prevent the little
"PyPeople" from hurting themselves by "handicapping" our
globals in the form of "module level" globals.
But even the "module level" globals can be accessed
"globally" if the module they are contained in is imported
everywhere.
import glomod
glomod.var # Access
global.var = newValue
Which leads me to the conclusion that the designers were
either naive or underestimated the chutzpah of this fine
community.
============================================================
The Power of the 1%:
============================================================
Most of this "fear of globals" can be traced back to a
minority of naive coders who used globals haphazardly and
were hurt by them, <sarcasm>and now we ALL have to suffer
because future idiots need to be protected from themselves!
</sarcasm>
Too many times I've seen idiotic uses for globals.
One more atrocious example was "dialog return values" stored
as globals so the "dumb coder" could eaisly restore the
previous state of the dialog values between successive
calls.
Obviously the best solution would be for the dialog object
ITSELF to store (and restore) the values when necessary, but
alas, here i am again expecting people to create interfaces
that are consistent and logical. *rolls-eyes*
Of course we can only blame the dialog designer and not the
caller for this design flaw, but the caller still has no
excuse for globally storaging these values.
If the caller cannot repair the mistake by extending the
dialog object himself, then he can store the values within
the current module or class level scope. There is no excuse
for elevating this information to global scope.
However, there ARE justified uses of global variables!
============================================================
Justifying Global Variables:
============================================================
Globals are justified when they are used to communicate
information between scopes that otherwise were meant to be
mutually exclusive. One good example would be package sub-
modules.
Now. Some might believe that the purity of namespaces
becomes tainted if they can be violently penetrated by
global variables. But again, they are falling back on gut
reactions fostered from years of brain washing. Yes, globals
can be bad (if misused), but for the most part they are
crucial to transferring information CLEANLY between isolated
namespaces
But even globals themselves are not good enough UNLESS we
engineer a "global hierarchy"!
============================================================
From Flat to Nested == From Tricked to Bested:
============================================================
One of the shortcomings of the current implementation of
global variables is their inherent "flat" access nature.
There is no hierarchy of globals, and once all the good
names are taken, your screwed!
"But Rick, even when we use globals, we don't need that many"
Only if you consider the single package that represents your
program, but what about the thousands of support libraries
with millions of lines of code that work in the background
to make your measly few thousand lines of code work? What
about all the globals that they have injected?
"Never thought of that really"
Throwing out global names UNADORNED is folly. Could you
imagine telephone numbers without area codes?
Hmm: Am i calling "Jim" in Beverly Hills California???
california.beverlyhills.jim
or "Jim" in "Spokane Washington"???
washington.spokane.jim
You see, you need to QUALIFY these names not only to make
then unique, but also so the caller will understand who he
is calling.
Same goes for globals.
[toc] | [next] | [standalone]
| From | Tim Daneliuk <tundra@tundraware.com> |
|---|---|
| Date | 2013-11-11 20:47 -0600 |
| Message-ID | <deh8la-8p4.ln1@ozzie.tundraware.com> |
| In reply to | #59142 |
On 11/11/2013 08:06 PM, Rick Johnson wrote: > Globals are justified when they are used to communicate > information between scopes that otherwise were meant to be > mutually exclusive. I think this is certainly the use case most people would suggest. But I think you may have missed the real reason most modern designers object to inter-module globals: The presence of such entities almost always means the code has been designed badly. Whether we're writing pristine OO code (cough, cough) or more traditional procedural stuff, information hiding is a good thing. When and where there is a need for modules (or programs, or machines, or "clouds", or interstellar space ...) to share information, my view is this is better done via some sort of interface/message passing mechanism. The more "things" that have to be shared across modules/programs/machines/clouds/space ... the more *brittle* the end system becomes. This problem is broader than just variables, BTW. It exists anytime you share *anything* across many computational components, especially in highly parallel and/or distributed systems. For example, RPCs tend to be lousy at building high scale distributed system because they usually have a call-and-wait semantic which will fail if the caller never responds. In this case the system is sharing the semantics of *time*. As a general matter, exactly-once asynchronous messaging tends to be a better implementation model here. Just my 2 cents worth. Interesting read. Thanks for taking the time -- ---------------------------------------------------------------------------- Tim Daneliuk tundra@tundraware.com PGP Key: http://www.tundraware.com/PGP/
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-11 20:46 -0800 |
| Message-ID | <82561733-d131-45de-ab10-c847f1960dc4@googlegroups.com> |
| In reply to | #59145 |
On Monday, November 11, 2013 8:47:09 PM UTC-6, Tim Daneliuk wrote: > I think this is certainly the use case most people would > suggest. But I think you may have missed the real reason > most modern designers object to inter-module globals: The > presence of such entities almost always means the code has > been designed badly. Whether we're writing pristine OO > code (cough, cough) or more traditional procedural stuff, > information hiding is a good thing. Yes, and i agree. But you cannot "hide" everything. There will always be a need to share information. > When and where there is a need for modules (or programs, > or machines, or "clouds", or interstellar space ...) to > share information, my view is this is better done via some > sort of interface/message passing mechanism. But python modules can't be interfaces because interfaces should protect internal data, prevent external forces from meddling with internal state (EXCEPT via the rules of a predefined "contract"), hide dirty details from the caller, and have clearly defined access points. BUT PYTHON MODULES DON'T FOLLOW THIS DESIGN PATTERN! No, Python modules can be poked, prodded, and violated by any pervert who can spell the word "import". Attribute values can be reassigned and state can be externally manipulated resulting in all types of undefined behaviors -- that does not sound like an interface to me. So if python modules are importable everywhere, and mutable from everywhere, then python modules are merely addresses to a collection of global variables? And they're only interfaces "superficially"? So that leaves us with Python's current implementation of unofficial "global" variables implemented as "puesdo- interfaces" by module objects that are victims waiting to be violated. Interesting. IF IT WALKS LIKE A GLOBAL DUCK AND...
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-11-12 16:02 +1100 |
| Message-ID | <mailman.2427.1384232570.18130.python-list@python.org> |
| In reply to | #59148 |
On Tue, Nov 12, 2013 at 3:46 PM, Rick Johnson <rantingrickjohnson@gmail.com> wrote: > But python modules can't be interfaces because interfaces > should protect internal data, prevent external forces from > meddling with internal state (EXCEPT via the rules of a > predefined "contract"), hide dirty details from the caller, > and have clearly defined access points. > > BUT PYTHON MODULES DON'T FOLLOW THIS DESIGN PATTERN! > > No, Python modules can be poked, prodded, and violated by > any pervert who can spell the word "import". And C++ objects can be poked by anyone who can do a pointer cast. And Java objects by anyone who notices that 'const' checks don't apply to byte-code. In fact, the only language I can think of that actually "prevent[s] external forces from meddling with internal state" is HQ9++, which follows the very best principles of data hiding. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ricardo Aráoz <ricaraoz@gmail.com> |
|---|---|
| Date | 2013-11-12 07:15 -0300 |
| Message-ID | <mailman.2455.1384255312.18130.python-list@python.org> |
| In reply to | #59148 |
El 12/11/13 01:46, Rick Johnson escribió: > No, Python modules can be poked, prodded, and violated by any pervert > who can spell the word "import". Attribute values can be reassigned > and state can be externally manipulated resulting in all types of > undefined behaviors -- Nice! My code, my responsibility, my business.... not yours. > that does not sound like an interface to me. So if python modules are > importable everywhere, and mutable from everywhere, then python > modules are merely addresses to a collection of global variables? And > they're only interfaces "superficially"? So that leaves us with > Python's current implementation of unofficial "global" variables > implemented as "puesdo- interfaces" by module objects that are victims > waiting to be violated. Interesting. IF IT WALKS LIKE A GLOBAL DUCK > AND... Nice choice of words, "violated", "victims".... Really conductive to a balanced unprejudiced thought process.
[toc] | [prev] | [next] | [standalone]
| From | Tim Chase <python.list@tim.thechases.com> |
|---|---|
| Date | 2013-11-12 05:32 -0600 |
| Message-ID | <mailman.2457.1384255840.18130.python-list@python.org> |
| In reply to | #59148 |
On 2013-11-11 20:46, Rick Johnson wrote: > Yes, and i agree. But you cannot "hide" everything. There > will always be a need to share information. You may not be able to (or want to) hide everything, but sharing should at least happen over defined protocols (functions/methods). Otherwise, you wander off into the weeds of hackery and monkey-patching which makes maintaining the code a lot hairier. -tkc
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-11-12 20:20 -0500 |
| Message-ID | <mailman.2517.1384305627.18130.python-list@python.org> |
| In reply to | #59148 |
On 11/11/2013 11:46 PM, Rick Johnson wrote: > No, Python modules can be poked, prodded, and violated by > any pervert who can spell the word "import". Or by clever programmers. > Attribute values can be reassigned and state can be > externally manipulated Perhaps for good reasons. > resulting in all types of undefined behaviors Not necessarily. Manipulation can also eliminate undefined behaviors. Suppose I want to test a Idle function that uses a tkinter.messagebox class to communicate with users. Perhaps the module has from tkinter.messagebox import askretrycancel The behavior of askretrycancel(*args) is undefined insofar as it depends on the arbitrary actions of a human user (it may even hang forever). In an automated test, there is no user, and it is difficult to simulate the eyes and fingers of one while leaving askretrycancel as it is. Monkeypatching with a mock solves this. Simplifying a bit, and leaving out details, I have done something like this. from mock_tkinter import mbox # mocks all messageboxes mock_arc = mbox() import mod mod.askretrycancel = mock_arc This makes mod.askretrycancel deterministic in that I can preload a response into mock_arc before calling the function or method in mod. (This simulates a user's fingers.) The mock also saves the values sent to it to see if they are what they should be. (This simulates a user's eyes.) -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Tim Daneliuk <tundra@tundraware.com> |
|---|---|
| Date | 2013-11-13 18:17 -0600 |
| Message-ID | <52841692.5080406@tundraware.com> |
| In reply to | #59148 |
On 11/11/2013 10:46 PM, Rick Johnson wrote: > On Monday, November 11, 2013 8:47:09 PM UTC-6, Tim Daneliuk wrote: >> I think this is certainly the use case most people would >> suggest. But I think you may have missed the real reason >> most modern designers object to inter-module globals: The >> presence of such entities almost always means the code has >> been designed badly. Whether we're writing pristine OO >> code (cough, cough) or more traditional procedural stuff, >> information hiding is a good thing. > > Yes, and i agree. But you cannot "hide" everything. There > will always be a need to share information. > >> When and where there is a need for modules (or programs, >> or machines, or "clouds", or interstellar space ...) to >> share information, my view is this is better done via some >> sort of interface/message passing mechanism. > > But python modules can't be interfaces because interfaces > should protect internal data, prevent external forces from > meddling with internal state (EXCEPT via the rules of a > predefined "contract"), hide dirty details from the caller, > and have clearly defined access points. > > BUT PYTHON MODULES DON'T FOLLOW THIS DESIGN PATTERN! I think this is an unfair criticism. You can do this in ANY language if you know how. For example, if I understand stack frames, I can write code that fiddles with local variables in compiled code. For that matter, if I understand pointers at the assembler level, I can probably do the same with globals. Global access/visibility is a matter of convenience - it's harder to do in a static compiled language and easier to do in a late bound, dynamic language. The fact that this is *possible* in Python doesn't speak to Python's fitness for any particular purpose nor does it speak to whether globals are a good- or bad idea. Anyone that knows enough to fiddle with the internal implementation of a module and or subvert global constants like math.pi, also know what they're doing is "perverse" and have to be willing to live with the side effects and consequences of such acts. I cut my teeth in this business writing realtime machine control software in assembly language (and PL/M!) where there was NO memory protection and everything - code, data, stack - was "global" in some sense, or at least could be made to be. We managed to routinely write highly reliable, blazingly fast code that didn't break, didn't bork, and did what it was supposed to. There's no reason to believe that Python programs cannot do the exact same thing (well, not the realtime part) with just as much robustness and correctness as those old asm programs. Programming well has far less to do with the language and has far more to do with the designer and coder... ---------------------------------------------------------------------------- Tim Daneliuk tundra@tundraware.com PGP Key: http://www.tundraware.com/PGP/
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-13 18:25 -0800 |
| Message-ID | <9da73e20-432a-4c3c-a1a5-e78e5144c511@googlegroups.com> |
| In reply to | #59365 |
On Wednesday, November 13, 2013 6:17:22 PM UTC-6, Tim Daneliuk wrote: > > But python modules can't be interfaces because interfaces > > should protect internal data, prevent external forces from > > meddling with internal state (EXCEPT via the rules of a > > predefined "contract"), hide dirty details from the caller, > > and have clearly defined access points. > > BUT PYTHON MODULES DON'T FOLLOW THIS DESIGN PATTERN! > I think this is an unfair criticism. You can do this in > ANY language if you know how. For example, if I understand > stack frames, I can write code that fiddles with local > variables in compiled code. For that matter, if I understand > pointers at the assembler level, I can probably do the same > with globals. And if i understand file systems, and i have access to your computer, i can delete the contents of your hard disc :-). We can take this analogy all the way to it's absurd conclusions, but we have not proven anything. > Programming well has far less to do with the language and > has far more to do with the designer and coder... I very much agree.
[toc] | [prev] | [next] | [standalone]
| From | jongiddy <jongiddy@gmail.com> |
|---|---|
| Date | 2013-11-12 06:12 -0800 |
| Message-ID | <d1bb2f3b-d5d7-4336-8984-3871ecf5a16e@googlegroups.com> |
| In reply to | #59142 |
On Tuesday, November 12, 2013 2:06:09 AM UTC, Rick Johnson wrote: > > ============================================================ > > Justifying Global Variables: > > ============================================================ > > Globals are justified when they are used to communicate > > information between scopes that otherwise were meant to be > > mutually exclusive. One good example would be package sub- > > modules. > Can you please give an example where having a module provide a global variable would work better than any of: 1. providing a module function to change the operation of my module 2. providing a class with a method to change the operation of an instance 3. providing an additional parameter to module functions / instance methods to change operation 4. providing additional module functions / instance methods to perform different operations
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-12 07:05 -0800 |
| Message-ID | <d0b7995e-72c3-4c6d-bac3-d9f90bc91b39@googlegroups.com> |
| In reply to | #59196 |
On Tuesday, November 12, 2013 8:12:10 AM UTC-6, jongiddy wrote:
> Can you please give an example where having a module
> provide a global variable would work better than any of:
> [snip]
Well my point is that the attributes of any Python module
are "emulating" globals already. The fact that we have to
mutate them via a "psuedo" interface makes us "falsely"
believe we are using an interface -- but we aren't!
PYTHON MADE ACCESSING GLOBAL VARIABLES MORE DIFFICULT!
As example. I could import the math module and start
fiddling with attributes. Let's say for example i can change
the value of math.pi. Most people would probably say "what's
the problem with that?", here, let me show you.
# mod1.py
print "mod1.py"
import math
math.pi = "tasty"
# mod2.py
print "mod2.py"
import math
print ' value of math.pi is:', math.pi
radius = 10
math.pi * radius
#modmain.py
import mod1
import mod2
print dir(mod1)
print dir(mod2)
When you run "modmain.py" you will see that not only have we
changed the global variable "pi" to a string, but thanks to
a dumb overloading of the multiply operator, python will
happily give use the wrong answer -- but that's another
problem, let's stay focused on the "global" problem for now!
When i type "math.pi", i "feel" as though i'm accessing an
interface, BUT I'M NOT! If i was indeed accessing a TRUE
interface, the interface would have thrown a Type error for
attempting to assign a value of type string to what should
only be a float. The interface would have protected it's
internal data from corruption, but it didn't.
BECAUSE IT'S NOT AN INTERFACE!
It's just a dumb namespace with no exposed hooks to control
it's underlying behavior.
MY POINT IS:
Python designers act like globals are SO evil, but then they
give us modules which are containers for global variables,
and now the globals contained within those modules are
wolves in sheep's clothing. Are they just trying to fool
themselves, or fool us?
FOOD FOR THOUGHT:
What's worse? A wolf? Or a wolf in sheep's clothing?
[toc] | [prev] | [next] | [standalone]
| From | jongiddy <jongiddy@gmail.com> |
|---|---|
| Date | 2013-11-12 07:33 -0800 |
| Message-ID | <4bef88d0-d3eb-42e5-ac8e-288c629c528e@googlegroups.com> |
| In reply to | #59202 |
On Tuesday, November 12, 2013 3:05:25 PM UTC, Rick Johnson wrote: > > > > When i type "math.pi", i "feel" as though i'm accessing an > > interface, BUT I'M NOT! I'm not sure where you get the feeling you're accessing an interface. If I typed this, I would feel like I was trying to change a fundamental constant. You have just demonstrated that going into other modules and changing their attributes (whether they are variables, functions or classes) is generally a BAD idea, and I don't think I've ever seen anyone recommend doing this, except possibly as a workaround or for debugging purposes. On the other hand, you initially suggested that modifying globals contained within namespaces (i.e. modules) is a good way to communicate between modules. That is, you suggested in your initial post that going into other modules and changing their attributes is a GOOD idea. This inconsistency is why I was asking for a good example (i.e. a realistic example where the use of global variables provides the best solution). Just because a tool allows you to do something does not make it a good idea. Try this paraphrase of your last post: Ladder designers act like standing on the top rung is SO evil, but then they give us ladders with a top rung, Are they just trying to fool themselves, or fool us?
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-12 09:00 -0800 |
| Message-ID | <2a325d8a-a242-4f2a-861b-9b786600f886@googlegroups.com> |
| In reply to | #59206 |
On Tuesday, November 12, 2013 9:33:50 AM UTC-6, jongiddy wrote:
> I'm not sure where you get the feeling you're accessing an
> interface.
Because the constant PI should never change. Sure we can
argue about granularity of PI, but that argument has no
weight on the fact that PI should be a constant.
By placing PI in the module "math", we are creating a pseudo
interface. We (the creators) are "assuming" that PI will be a
constant and never change, and the caller is assuming that
pi will remain static, but not only can it be mutated, it
can be mutated globally.
math.pi is neither a constant nor a local module attribute,
math.pi is really a global variable. This is true not only
for math.pi, but ALL attributes of ALL python modules.
> If I typed this, I would feel like I was trying
> to change a fundamental constant. You have just
> demonstrated that going into other modules and changing
> their attributes (whether they are variables, functions or
> classes) is generally a BAD idea, and I don't think I've
> ever seen anyone recommend doing this, except possibly as
> a workaround or for debugging purposes. On the other hand,
> you initially suggested that modifying globals contained
> within namespaces (i.e. modules) is a good way to
> communicate between modules.
You missed my point: only IF python modules were TRUE
interfaces. It's not a good idea under python's current
implementation of modules. My thread is intended to
underscore this very design flaw.
> This inconsistency
There is no inconsistency in my logic, quite the contrary.
I think you're having difficulty following along because
you've been brainwashed by Python for too long. You've
falsely believed that Python does not have globals, but
it does! You just have to mutate then via a pseudo
interface.
> is why I was asking for a good example (i.e.
> a realistic example where the use of global variables
> provides the best solution).
I gave a good example in my very first post:
RR: "Globals are justified when they are used to
[share] information between scopes that otherwise
were meant to be mutually exclusive. One good
example would be package sub-modules."
> Just because a tool allows you to do something does not
> make it a good idea. Try this paraphrase of your last
> post: Ladder designers act like standing on the top rung
> is SO evil, but then they give us ladders with a top rung,
> Are they just trying to fool themselves, or fool us?
EXACTLY. And whilst your comparison is both intelligent and
funny, you're just re-iterating my point!
We have all been brainwashed by authorities. First they
give us rules, then they give us the power to break
those rules. If standing on the top rung is SO
dangerous, then don't manufacture your ladders with top
rungs. Else, shut up about it!
"THOU SHALT NOT KILL"
Well i can't live WITH the B!@$%!!!
"THOU SHALT NOT COMMIT ADULTERY"
Then why create me with a unquenchable desire for sex?
"THOU SHALT NOT TAKE THE LORDS NAME IN VAIN"
GOD DAMMIT! Stop making all these opposing rules.
So the designers detest globals huh? But python module
attributes are really global because they can be accessed
and mutated ANYWHERE!". This enigma leads to two logical
design philosophies: (anything else is folly)
1. Accept that globals are useful, and make them
available through a "real" global syntax, not
some attribute of a module that "appears" to be
local, but in reality is global. Then prevent
external mutation of module attributes directly,
and instead, require that mutation must follow a
contract defined by internal module "setter"
functions.
2. Remain convinced that global mutation is evil
and prevent mutation of all python module
attributes. You can import modules, but you can't
mutate their contents.
THIS IS HOW YOU DESIGN FOR CONSISTENCY, NOT HYPOCRISY!
@LanguageDesigners: But whatever you do, don't hide globals
behind pseudo interfaces, because then you have created
something worse than a global; you've created a global in
sheep's clothing. And you're a hypocrite.
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-12 09:42 -0800 |
| Message-ID | <b40c75e8-1c4d-4570-9a8a-126b08ba7b8c@googlegroups.com> |
| In reply to | #59222 |
On Tuesday, November 12, 2013 11:00:37 AM UTC-6, Rick Johnson wrote: [snip] > We have all been brainwashed by authorities. First they > give us rules, then they give us the power to break > those rules. The devil himself said it best: http://www.youtube.com/watch?v=RGR4SFOimlk Hmm. How do we humans cope with all these opposing rules? If we created an AI with all the ridiculous, convoluted and opposing rules that we humans live with on a daily basis, it would blow chunks. How do our minds possibly cope with such illogical rules without blowing chunks? We cope by re-inventing reality. We cope by convincing ourselves that truths are not true and lies are true. We cope by designing languages that obfuscate globals behind pseudo interfaces so we can get farm fuzzy feelings in our tummy, then we can "secretly" break the rule when non-one is looking. By doing this we convince ourselves that we are "pure". HUMANS: What a pathetic bunch of slaves! http://www.youtube.com/watch?v=PFdmAgA_Gfo
[toc] | [prev] | [next] | [standalone]
| From | Tim Chase <python.list@tim.thechases.com> |
|---|---|
| Date | 2013-11-12 11:45 -0600 |
| Message-ID | <mailman.2484.1384278220.18130.python-list@python.org> |
| In reply to | #59222 |
On 2013-11-12 09:00, Rick Johnson wrote: > Because the constant PI should never change. Sure we can > argue about granularity of PI, but that argument has no > weight on the fact that PI should be a constant. > > By placing PI in the module "math", we are creating a pseudo > interface. We (the creators) are "assuming" that PI will be a > constant and never change, and the caller is assuming that > pi will remain static, but not only can it be mutated, it > can be mutated globally. But the module-scoping of "globals" is perfectly valid: >>> print(math.PI) 3.1415926535897932 >>> print(Magnum.PI) "Tom Selleck" As an example from the stdlib of setting globals via a protocol, locale.setlocale() does exactly this. So I'm not sure why you have your knickers in a knot. Module-level items can be accessed globally (though often a bad idea, or at least you have to beware of side-effects where other things might break), and if you don't like the "modules are not objects", someone in this thread already showed you that you can insert objects/classes into the sys.modules and get full getter/setter functionality with minimal trouble. Finally, we're all (mostly) consenting adults here. If I want to be an idiot and math.PI = 3.14 and suddenly stuff breaks, I get to keep all the pieces my breakage caused. -tkc
[toc] | [prev] | [next] | [standalone]
| From | jongiddy <jongiddy@gmail.com> |
|---|---|
| Date | 2013-11-12 14:41 -0800 |
| Message-ID | <5234e28a-8d7f-4a84-a1de-c5144fa869e6@googlegroups.com> |
| In reply to | #59222 |
On Tuesday, November 12, 2013 5:00:37 PM UTC, Rick Johnson wrote: > > > 1. Accept that globals are useful, and make them > > available through a "real" global syntax, not > > some attribute of a module that "appears" to be > > local, but in reality is global. Then prevent > > external mutation of module attributes directly, > > and instead, require that mutation must follow a > > contract defined by internal module "setter" > > functions. > > > > 2. Remain convinced that global mutation is evil > > and prevent mutation of all python module > > attributes. You can import modules, but you can't > > mutate their contents. From your first post, I take it you're not keen on option #2. For #1, module globals are exactly the hierarchically namespaced globals that you desire in your first post, except they are variables, not get/set handlers (which is what I take you to mean by an "interface"). Why not create a PEP to provide handlers for module attributes? You could base it on PEP 213, which describes the same feature for classes. As a bonus, this would trivially support option #2 (e.g. non-mutable math.pi) by raising an exception for the set operator.
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-12 18:45 -0800 |
| Message-ID | <e9d548f9-19a7-4e63-82bc-19d021c7544b@googlegroups.com> |
| In reply to | #59240 |
On Tuesday, November 12, 2013 4:41:34 PM UTC-6, jongiddy wrote: > On Tuesday, November 12, 2013 5:00:37 PM UTC, Rick Johnson wrote: > > 1. Accept that globals are useful, and make them > > available through a "real" global syntax, not > > some attribute of a module that "appears" to be > > local, but in reality is global. Then prevent > > external mutation of module attributes directly, > > and instead, require that mutation must follow a > > contract defined by internal module "setter" > > functions. > > 2. Remain convinced that global mutation is evil > > and prevent mutation of all python module > > attributes. You can import modules, but you can't > > mutate their contents. > From your first post, I take it you're not keen on option #2. That is correct, i prefer to use REAL interfaces. > For #1, module globals are exactly the hierarchically > namespaced globals that you desire in your first post, Agreed. > except they are variables, not get/set handlers (which is > what I take you to mean by an "interface"). Yes, python modules expose ALL members publicly and have no support for contractual interfacing. > Why not create a PEP to provide handlers for module > attributes? You could base it on PEP 213, which describes > the same feature for classes. I would love to see modules expand to something more than mere "boxes to stuff variables". But then again, modules are not going to provide the ease of access that globals demand due to the import problem. Modules will not be a good place to store globals because modules must be imported and globals should never need importing. I've just released a module on Python-list called "G.py" that does exactly what i propose. It's not perfect, but i think you'll understand what i'm proposing after testing it. > As a bonus, this would trivially support option #2 (e.g. > non-mutable math.pi) by raising an exception for the set > operator. "math.pi" should be "math.PI". and PI should be a CONSTANT. And not just a pseudo constant, but a REAL constant that cannot be changed.
[toc] | [prev] | [next] | [standalone]
| From | Tim Chase <python.list@tim.thechases.com> |
|---|---|
| Date | 2013-11-12 21:22 -0600 |
| Message-ID | <mailman.2522.1384312844.18130.python-list@python.org> |
| In reply to | #59278 |
On 2013-11-12 18:45, Rick Johnson wrote:
> "math.pi" should be "math.PI".
It's a real shame that this fails:
>>> math.PI = math.pi
oh...wait...
> and PI should be a CONSTANT. And not just a pseudo constant, but a
> REAL constant that cannot be changed.
How much precision do you want? Perhaps you really do want do just
use because you know you only have 2-3 places of precision in your
other numbers:
math.pi = 3.14
Or maybe you want to monkey-patch in a fraction/decimal instead for
greater precision:
math.pi = decimal.Decimal('3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679')
It comes back to Python being a language for consenting adults.
-tkc
[toc] | [prev] | [next] | [standalone]
| From | Andrew Cooper <root@127.0.0.1> |
|---|---|
| Date | 2013-11-13 22:00 +0000 |
| Message-ID | <LDSgu.163030$jf3.19506@fx04.am4> |
| In reply to | #59278 |
On 13/11/2013 02:45, Rick Johnson wrote: > > "math.pi" should be "math.PI". and PI should be a CONSTANT. > And not just a pseudo constant, but a REAL constant that > cannot be changed. > And what do you do when the wizards bend space-time to make PI exactly 3, for the ease of other calculations when building a sorting machine? Does usenet start delivering these posts in the past/future? I suspect real python programmers will be able to feel quite smug when they can change the value of math.pi to suit the situation. ~Andrew
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-11-13 18:16 -0800 |
| Message-ID | <1329c04c-8f38-4525-87a7-2ddbc8414525@googlegroups.com> |
| In reply to | #59348 |
On Wednesday, November 13, 2013 4:00:15 PM UTC-6, Andrew Cooper wrote: > And what do you do when the wizards bend space-time to > make PI exactly 3, for the ease of other calculations when > building a sorting machine? Are you telling me that these wizards can't be bothered to write the integer "3"? They have to reassign math.pi instead? Look if you need some other granularity of PI besides what's offered in math.PI, then do your own calculation. The last thing you want to do is create a variable when a constant is what you need.
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.python
csiph-web