Sharing package data across files

2016-06-28 Thread scottpakin1
I'm trying to create a package in which the constituent files share some state. 
 Apparently, I don't understand scopes, namespaces, and package semantics as 
well as I thought I did.  Here's the directory structure for a simplified 
example:

   example/
 __init__.py
 vars.py
 funcs.py

vars.py defines a single variable:

foo = 123

funcs.py defines a function that reads and writes that variable:

def bar():
global foo
foo += 1
return foo

__init__.py exposes both of those to the caller:

from vars import foo
from funcs import bar

Alas, it seems the bar function does not reside in the same global scope as the 
foo variable:

>>> from example import foo, bar
>>> foo
123
>>> bar()
Traceback (most recent call last):
  File "", line 1, in 
  File "example/funcs.py", line 3, in bar
foo += 1
NameError: global name 'foo' is not defined

How can I make the example package work like one integrated module even though 
in reality it's split across multiple files?

Thanks,
-- Scott
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Sharing package data across files

2016-06-28 Thread scottpakin1
On Tuesday, June 28, 2016 at 4:37:45 PM UTC-6, Michael Selik wrote:
> Why do you want to?

I have a standalone script that grew and grew until reaching an unmaintainable 
size.  I was hoping to refactor it into a relatively small top-level script 
plus a package containing a bunch of relatively small files.

> Isn't easier to have the ``funcs`` module import the ``vars`` module?

Easier, yes.  Correct, no:

from vars import foo

def bar():
global foo
foo += 1
return foo

which surprisingly (to me, anyway) changes a _copy_ of foo, not the foo I'd 
think of as belonging to the example package:

>>> from example import foo, bar
>>> foo
123
>>> bar()
124
>>> foo
123

> Even easier, paste all the code into a single file.

That kind of defeats my goal of splitting a single file into more maintainable 
chunks.

Thanks,
-- Scott
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Sharing package data across files

2016-06-28 Thread scottpakin1
On Tuesday, June 28, 2016 at 5:20:16 PM UTC-6, John Pote wrote:
> Correct me if I'm wrong but is not the above only true if bar has been 
> assigned to and thus references an imutable object? In your example the 
> string "oranges".
> If bar has been assigned to a mutable object in module foo then every 
> module importing via "from foo import bar" will all import the name bar 
> pointing to the same mutable object. If this mutable obj is changed via 
> bar in one module then every other module importing bar will also see 
> the change.
> eg
> In module foo:
>  bar = ["apples","bananas","grapes"]
> 
> In module bar1
>  from foo import bar
>  bar[0] = "oranges"
> 
> In module barx at some later time
>  from foo import bar
>  ...
>  print bar#prints ["oranges","bananas","grapes"]

That does seem to be the case.  Making my example look like the above, with foo 
being assigned a list and bar mutating the first element of the list, indeed 
results in foo being updated:

>>> from example import foo, bar
>>> foo
['apples', 'bananas', 'grapes']
>>> bar()
['oranges', 'bananas', 'grapes']
>>> foo
['oranges', 'bananas', 'grapes']

> If my understanding here is correct then this would be a good case for 
> never directly writing to a globle. Use getter()s and setter()s to make 
> it obvious that any use of the setter() will be seen by all future calls 
> to the getter().

Yeah, it looks like I'll have to do more to my original (big) code than simply 
partition it into appropriate-sized chunks and drop it into a package 
directory.  Oh, well.

Thanks,
-- Scott
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Sharing package data across files

2016-06-28 Thread scottpakin1
Steven,

Very helpful!  Thanks for the thorough explanation.

-- Scott
-- 
https://mail.python.org/mailman/listinfo/python-list