Sharing package data across files
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
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
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
Steven, Very helpful! Thanks for the thorough explanation. -- Scott -- https://mail.python.org/mailman/listinfo/python-list
