Re: from xx import yy

2017-11-17 Thread Bob van der Poel
On Thu, Nov 16, 2017 at 2:46 PM, Cameron Simpson  wrote:

> 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

2017-11-16 Thread Cameron Simpson

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
--
https://mail.python.org/mailman/listinfo/python-list


Re: from xx import yy

2017-11-16 Thread bvdp
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

2017-11-14 Thread Cameron Simpson

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)

2017-11-14 Thread Lawrence D’Oliveiro
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

2017-11-13 Thread Rick Johnson
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

2017-11-13 Thread Chris Angelico
On Tue, Nov 14, 2017 at 3:58 AM, bvdp  wrote:
> 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

2017-11-13 Thread bvdp
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

2017-11-13 Thread Rick Johnson
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

2017-11-12 Thread Chris Angelico
On Mon, Nov 13, 2017 at 1: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)
>
> 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

2017-11-12 Thread Ned Batchelder

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

2017-11-12 Thread bvdp
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