from xx import yy

Cameron Simpson cs at cskk.id.au
Tue Nov 14 16:20:17 EST 2017


On 13Nov2017 08:58, bvdp <bob at 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 <cs at cskk.id.au> (formerly cs at zip.com.au)



More information about the Python-list mailing list