Re: from xx import yy
On Thu, Nov 16, 2017 at 2:46 PM, Cameron Simpsonwrote: > On 16Nov2017 09:42, bvdp wrote: > >> In my original case, I think (!!!), the problem was that I had a variable >> in mod1.py and when I did the "from mod1 import myvarible" all was fine. >> Python create a new local-to-the-module variable and initialized it to the >> value it was set to in mod1. And at this point all is well. But, when mod1 >> changed the value of myvariable the change didn't get passed to the other >> modules. Of course, the reason for my confusion is that I'm thinking that >> python is using pointers :) Opps. >> >> Maybe we need pointers in python . >> > > Thinking about this as pointers works pretty well. We call them references > in Python because they are not (or need not be) memory addresses and C > pointers are memory addresses. However the model is the same: an arrow from > a variable name pointing at the place a value (the object) is stored. > > Look: > > mod1.py: x = 1 > > making: > > mod1.x --> 1 > > Now consider: > > mod2.py: from mod1 import x > > Making: > > mod1.x --> 1 > ^ > mod2.x + > > both referring to the "1" object. > > Now: > mod2.py: x = 2 > > Making: > > mod1.x --> 1 > mod2.x --> 2 > > You see that mod1 is not adjusted. Versus: > > mod2.py: import mod1 > > Making: > > mod2.mod1 --> mod1, mod1.x --> 1 > > Then: > > mod2.py: mod1.x = 2 > > Making: > > mod2.mod1 --> mod1, mod1.x --> 2 > > Because you're adjusting the reference "mod1.x", _not_ the distinct > reference "mod2.x". > > Cheers, > Cameron Simpson (formerly c...@zip.com.au) > > Draw little boxes with arrows. It helps. - Michael J. Eager > Yes, your examples work perfectly. It's when one does an "from mod1 import var" that it doesn't. In mod1 set var to a value. Lets use 5. Now, in mod2 we do: from mod1 import var And, yes, var is equal to 5. But, to the folks like me who are not complete pythonistas, we'd think it worked and was wonderful. But, if we change the variable in mod1 whit a function in mod1, the value doesn't change in mod2. The problem is that from/import does not create var as a pointer, but as a new variable. -- Listen to my FREE CD at http://www.mellowood.ca/music/cedars Bob van der Poel ** Wynndel, British Columbia, CANADA ** EMAIL: b...@mellowood.ca WWW: http://www.mellowood.ca -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On 16Nov2017 09:42, bvdpwrote: In my original case, I think (!!!), the problem was that I had a variable in mod1.py and when I did the "from mod1 import myvarible" all was fine. Python create a new local-to-the-module variable and initialized it to the value it was set to in mod1. And at this point all is well. But, when mod1 changed the value of myvariable the change didn't get passed to the other modules. Of course, the reason for my confusion is that I'm thinking that python is using pointers :) Opps. Maybe we need pointers in python . Thinking about this as pointers works pretty well. We call them references in Python because they are not (or need not be) memory addresses and C pointers are memory addresses. However the model is the same: an arrow from a variable name pointing at the place a value (the object) is stored. Look: mod1.py: x = 1 making: mod1.x --> 1 Now consider: mod2.py: from mod1 import x Making: mod1.x --> 1 ^ mod2.x + both referring to the "1" object. Now: mod2.py: x = 2 Making: mod1.x --> 1 mod2.x --> 2 You see that mod1 is not adjusted. Versus: mod2.py: import mod1 Making: mod2.mod1 --> mod1, mod1.x --> 1 Then: mod2.py: mod1.x = 2 Making: mod2.mod1 --> mod1, mod1.x --> 2 Because you're adjusting the reference "mod1.x", _not_ the distinct reference "mod2.x". Cheers, Cameron Simpson (formerly c...@zip.com.au) Draw little boxes with arrows. It helps. - Michael J. Eager -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On Tuesday, November 14, 2017 at 2:53:22 PM UTC-7, Cameron Simpson wrote: > On 13Nov2017 08:58, bvdp <b...@mellowood.ca> wrote: > >On Sunday, November 12, 2017 at 7:18:04 PM UTC-7, bvdp wrote: > >> I'm having a conceptual mind-fart today. I just modified a bunch of code > >> to use "from xx import variable" when variable is a global in xx.py. But, > >> when I change/read 'variable' it doesn't appear to change. I've written a > >> bit of code to show the problem: > >> > >> mod1.py > >> myvar = 99 > >> def setvar(x): > >> global myvar > >> myvar = x > >> > >> test1.py > >> import mod1 > >> mod1.myvar = 44 > >> print (mod1.myvar) > >> mod1.setvar(33) > >> print (mod1.myvar) > >> > >> If this test1.py is run myvar is fine. But, if I run: > >> > >> test2.py > >> from mod1 import myvar, setvar > >> myvar = 44 > >> print (myvar) > >> setvar(33) > >> print (myvar) > >> > >> It doesn't print the '33'. > >> > >> I thought (apparently incorrectly) that import as would import the name > >> myvar into the current module's namespace where it could be read by > >> functions in the module > > > >Thanks all for confirming that I was wrong to use "from .. import". Hmmm, > >perhaps for functions it might be okay. But, in most cases it's a lot more > >obvious to use module.function() when calling. Maybe a bit slower, but I'm > >sure it's negligible in most cases. > > You're wrong to use it for this particular special case, and ony because you > lose the reference to the module itself, which means you're no longer > accessing > the _reference_ "mod1.myvar", you're accessing a copy of the reference. So > the > wrong reference gets changed. > > In the general case, this isn't something people do a great deal. For most > imports you want access to things from the module with no intention of > changing > those references in the source module. > > So "from xx import yy" is perfectly find for that, the most common use case. > > Consider: > > from os.path import basename, dirname > > Is your code more readable with: > > from os.path import basename, dirname > base_of_parent_dir = basename(dirname(some_path)) > > or as: > > import os.path > base_of_parent_dir = os.path.basename(os.path.dirname(some_path)) > > particularly when you make lots of such calls? I much prefer the former. > > >And, yes, I am trying to share state info between modules. Is this a bad > >thing? I guess I would write getter() and setter() functions for all this. > >But > >that does seem to remind me too much of some other language :) > > In controlled situations it can be ok. Usually I define a small class for > this > kind of thing and keep all the state in class instances. That way it can > scale > (keeping multiple "states" at once). > > However, it does depend on your particular situation. I find situations where > I > want to directly change "global" values in other modules very rare, though > not > unknown. > > Cheers, > Cameron Simpson <c...@cskk.id.au> (formerly c...@zip.com.au) In my original case, I think (!!!), the problem was that I had a variable in mod1.py and when I did the "from mod1 import myvarible" all was fine. Python create a new local-to-the-module variable and initialized it to the value it was set to in mod1. And at this point all is well. But, when mod1 changed the value of myvariable the change didn't get passed to the other modules. Of course, the reason for my confusion is that I'm thinking that python is using pointers :) Opps. Maybe we need pointers in python . -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On 13Nov2017 08:58, bvdp <b...@mellowood.ca> wrote: On Sunday, November 12, 2017 at 7:18:04 PM UTC-7, bvdp wrote: I'm having a conceptual mind-fart today. I just modified a bunch of code to use "from xx import variable" when variable is a global in xx.py. But, when I change/read 'variable' it doesn't appear to change. I've written a bit of code to show the problem: mod1.py myvar = 99 def setvar(x): global myvar myvar = x test1.py import mod1 mod1.myvar = 44 print (mod1.myvar) mod1.setvar(33) print (mod1.myvar) If this test1.py is run myvar is fine. But, if I run: test2.py from mod1 import myvar, setvar myvar = 44 print (myvar) setvar(33) print (myvar) It doesn't print the '33'. I thought (apparently incorrectly) that import as would import the name myvar into the current module's namespace where it could be read by functions in the module Thanks all for confirming that I was wrong to use "from .. import". Hmmm, perhaps for functions it might be okay. But, in most cases it's a lot more obvious to use module.function() when calling. Maybe a bit slower, but I'm sure it's negligible in most cases. You're wrong to use it for this particular special case, and ony because you lose the reference to the module itself, which means you're no longer accessing the _reference_ "mod1.myvar", you're accessing a copy of the reference. So the wrong reference gets changed. In the general case, this isn't something people do a great deal. For most imports you want access to things from the module with no intention of changing those references in the source module. So "from xx import yy" is perfectly find for that, the most common use case. Consider: from os.path import basename, dirname Is your code more readable with: from os.path import basename, dirname base_of_parent_dir = basename(dirname(some_path)) or as: import os.path base_of_parent_dir = os.path.basename(os.path.dirname(some_path)) particularly when you make lots of such calls? I much prefer the former. And, yes, I am trying to share state info between modules. Is this a bad thing? I guess I would write getter() and setter() functions for all this. But that does seem to remind me too much of some other language :) In controlled situations it can be ok. Usually I define a small class for this kind of thing and keep all the state in class instances. That way it can scale (keeping multiple "states" at once). However, it does depend on your particular situation. I find situations where I want to directly change "global" values in other modules very rare, though not unknown. Cheers, Cameron Simpson <c...@cskk.id.au> (formerly c...@zip.com.au) -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy (Posting On Python-List Prohibited)
On Monday, November 13, 2017 at 3:18:04 PM UTC+13, bvdp wrote: > I'm having a conceptual mind-fart today. I just modified a bunch > of code to use "from xx import variable" when variable is a global > in xx.py. But, when I change/read 'variable' it doesn't appear to change. 1) Every name in Python is a variable. 2) Every distinct name (including qualifications) is a distinct variable. Changing one does not automatically change another. “from xx import yy” creates a variable named “yy” in the current scope, initialized to xx.yy but otherwise distinct from it. -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On Monday, November 13, 2017 at 10:59:06 AM UTC-6, bvdp wrote: > Thanks all for confirming that I was wrong to use "from .. > import". In this case, but i wouldn't extrapolate that advice to mean that the form `from X import Y` is _always_ bad. You just need to understand the consequences of each unique form of Python's import. > Hmmm, perhaps for functions it might be okay. But, > in most cases it's a lot more obvious to use > module.function() when calling. Well, again, i think you're over generalizing. If the imported symbol is a "self-contained code object" (aka: a function or a custom class, whether instanced or not), or especially a "read-only variable", then `from mod import x, y, z` won't typically cause any of these surprises. But of course, the previous paragraph only applies if i understood your initial question "correctly". Meaning, in the context of "your own personal expectations". My understanding of those _expectations_ (aka: _your_ expectations), is that you assumed that by importing a symbol (namely: `myvar`) into a "foreign module" (namely: "test2.py") that such action would allow you to mutate the _value_ of `myvar` from two distinct modules. But this is not true. Because each module creates its own local variables when names are imported. And that peculiarity is directly related to Python's strange implementation of global variables (psst: which, in the next paragraph, you'll discover are not really global at all!) (but for now, let's keep that dirty little secret between you and me, mmmkay?) One important lesson to learn about Python is that it has no "normally accepted" concept of "global variables". (meaning, variables that are known to all scopes within a program). So throw out everything you've ever know about global variables. Go ahead... We're waiting! Sure, you can create a _real_ global variable in Python if you were so inclined, but there is no "official support" for doing such a thing, and it requires some esoteric knowledge about how names are injected into module namespace by Python itself. But, to unlock this knowledge, you'll first to master the secret handshake and speakeasy a secret password. "Officially" speaking, the most promiscuous naturally occuring variable in a python program is what i call a "Module Level Variable" (or MLV for short). MLVs are the variables that are defined _outside_ of self-contained code objects like functions and/or classes, and these are the types of variables that require the use of the specialized `global` keyword (at least, if one wishes to modify them from inside a self-contained code object that is.) So basically, what you were trying to do was to create a global variable, a _real_ global variable that is, not the fake and utterly confusing ones that Python implements, nope, but a _real_, bonafide global variable that could be mutated from inside multiple modules (or more generically, multiple namespaces or scopes). And i'm sorry, but you're not allowed to do that. > Maybe a bit slower, but I'm sure it's negligible in most > cases. And, yes, I am trying to share state info between > modules. Is this a bad thing? I guess I would write > getter() and setter() functions for all this. But that does > seem to remind me too much of some other language :) I never write getters or setters unless i need functional behavior during the reading or writing of an attribute. IOW, if your getters and setters look like this: # pseudo some_value = "foo" def get_value(): return some_value def set_value(new): some_value = value ...then you're wasting your time and that of those who are forced to read the code. OTOH. If your getters and setters can justify their existence like this: # pseudo some_value = "foo" def get_value(): perform_some_test_or_action() return some_value def set_value(new): perform_some_test_or_action() some_value = new Then it makes sense to use them. Sometimes the value needs to be calculated; or updated; or type checked; or whatever. -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On Tue, Nov 14, 2017 at 3:58 AM, bvdpwrote: > Thanks all for confirming that I was wrong to use "from .. import". Hmmm, > perhaps for functions it might be okay. But, in most cases it's a lot more > obvious to use module.function() when calling. Maybe a bit slower, but I'm > sure it's negligible in most cases. > > And, yes, I am trying to share state info between modules. Is this a bad > thing? I guess I would write getter() and setter() functions for all this. > But that does seem to remind me too much of some other language :) > It's going to be so very marginally slower that you won't even be able to measure it, outside of a micro-benchmark. Worry about code correctness first, and then performance only if you actually know you have a problem. Sharing state between modules is fine as long as it's controlled by one module - which is what you have here. Go ahead! Not an issue. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On Sunday, November 12, 2017 at 7:18:04 PM UTC-7, bvdp wrote: > I'm having a conceptual mind-fart today. I just modified a bunch of code to > use "from xx import variable" when variable is a global in xx.py. But, when I > change/read 'variable' it doesn't appear to change. I've written a bit of > code to show the problem: > > mod1.py > myvar = 99 > def setvar(x): > global myvar > myvar = x > > test1.py > import mod1 > mod1.myvar = 44 > print (mod1.myvar) > mod1.setvar(33) > print (mod1.myvar) > > If this test1.py is run myvar is fine. But, if I run: > > test2.py > from mod1 import myvar, setvar > myvar = 44 > print (myvar) > setvar(33) > print (myvar) > > It doesn't print the '33'. > > I thought (apparently incorrectly) that import as would import the name myvar > into the current module's namespace where it could be read by functions in > the module Thanks all for confirming that I was wrong to use "from .. import". Hmmm, perhaps for functions it might be okay. But, in most cases it's a lot more obvious to use module.function() when calling. Maybe a bit slower, but I'm sure it's negligible in most cases. And, yes, I am trying to share state info between modules. Is this a bad thing? I guess I would write getter() and setter() functions for all this. But that does seem to remind me too much of some other language :) -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On Sunday, November 12, 2017 at 8:18:04 PM UTC-6, bvdp wrote: > I'm having a conceptual mind-fart today. I just modified a bunch of code to > use "from xx import variable" when variable is a global in xx.py. But, when I > change/read 'variable' it doesn't appear to change. I've written a bit of > code to show the problem: > > mod1.py > myvar = 99 > def setvar(x): > global myvar > myvar = x > > test1.py > import mod1 > mod1.myvar = 44 > print (mod1.myvar) > mod1.setvar(33) > print (mod1.myvar) > > If this test1.py is run myvar is fine. But, if I run: > > test2.py > from mod1 import myvar, setvar > myvar = 44 > print (myvar) > setvar(33) > print (myvar) > > It doesn't print the '33'. > > I thought (apparently incorrectly) that import as would > import the name myvar into the current module's namespace > where it could be read by functions in the module No. > test2.py > from mod1 import myvar, setvar Be aware that the previous line creates a _local_ "module- level variable" (in test2.py) named `myvar`, and assigns it the value of `99`. And also be aware that changes to this variable will not be reflected in `mod1'. As they are in no way connected. However, *SNIFF-SNIFF*, i smell a major flaw in this design. Why would you create a function to modify a module level variable anyway? If you want to modify a MLV from another module (aka: externally), then why not modify it using an explicit dot path? Observe: # from inside an external module import mod1 mod1.myvar = "foo" Now `myvar` is a string. So what is the point of this external modification? Are you attempting to share state between modules? -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On Mon, Nov 13, 2017 at 1:17 PM, bvdpwrote: > I'm having a conceptual mind-fart today. I just modified a bunch of code to > use "from xx import variable" when variable is a global in xx.py. But, when I > change/read 'variable' it doesn't appear to change. I've written a bit of > code to show the problem: > > mod1.py > myvar = 99 > def setvar(x): > global myvar > myvar = x > > test1.py > import mod1 > mod1.myvar = 44 > print (mod1.myvar) > mod1.setvar(33) > print (mod1.myvar) > > If this test1.py is run myvar is fine. But, if I run: > > test2.py > from mod1 import myvar, setvar > myvar = 44 > print (myvar) > setvar(33) > print (myvar) > > It doesn't print the '33'. > > I thought (apparently incorrectly) that import as would import the name myvar > into the current module's namespace where it could be read by functions in > the module It imports the *value*. What you have is basically this: import mod1 myvar = mod1.myvar setvar = mod1.setvar Since functions remember their contexts, setvar() still sees the globals of mod1. But myvar is a simple integer, so it's basically "myvar = 99". So basically, you can't from-import anything that's going to be changed. You can import constants that way ("from stat import S_IREAD"), or classes/functions (since they're not generally rebound), but as a general rule, don't from-import anything mutable. In fact, if you follow the even-more-general rule of "don't bother with from-imports at all", you'll be right far more than you'll be wrong. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: from xx import yy
On 11/12/17 9:17 PM, bvdp wrote: I'm having a conceptual mind-fart today. I just modified a bunch of code to use "from xx import variable" when variable is a global in xx.py. But, when I change/read 'variable' it doesn't appear to change. I've written a bit of code to show the problem: mod1.py myvar = 99 def setvar(x): global myvar myvar = x test1.py import mod1 mod1.myvar = 44 print (mod1.myvar) mod1.setvar(33) print (mod1.myvar) In this case "mod1" is a name in test1 that refers to the mod1 module. You can access and assign attributes on that module. Anyone else referencing that module (including the module itself) will see those changed attributes. If this test1.py is run myvar is fine. But, if I run: test2.py from mod1 import myvar, setvar myvar = 44 print (myvar) setvar(33) print (myvar) It doesn't print the '33'. In this case, "myvar" is a name that references the same value as mod1.myvar. Now both myvar and mod1.myvar refer to the same value. There is no direct connection between the myvar name and the mod1.myvar name. When you reassign myvar, it now refers to some other value. mod1.myvar is unaffected. --Ned. I thought (apparently incorrectly) that import as would import the name myvar into the current module's namespace where it could be read by functions in the module -- https://mail.python.org/mailman/listinfo/python-list
from xx import yy
I'm having a conceptual mind-fart today. I just modified a bunch of code to use "from xx import variable" when variable is a global in xx.py. But, when I change/read 'variable' it doesn't appear to change. I've written a bit of code to show the problem: mod1.py myvar = 99 def setvar(x): global myvar myvar = x test1.py import mod1 mod1.myvar = 44 print (mod1.myvar) mod1.setvar(33) print (mod1.myvar) If this test1.py is run myvar is fine. But, if I run: test2.py from mod1 import myvar, setvar myvar = 44 print (myvar) setvar(33) print (myvar) It doesn't print the '33'. I thought (apparently incorrectly) that import as would import the name myvar into the current module's namespace where it could be read by functions in the module -- https://mail.python.org/mailman/listinfo/python-list