Project-wide variable...

G

Gnarlodious

Is there a way to declare a project-wide variable and use that in all
downstream modules?

-- Gnarlir
 
N

Noah Hall

Is there a way to declare a project-wide variable and use that in all
downstream modules?

Well, the standard way you should do it is to use import to import a
certain variable - for example -

a.py -

x = 3

3
 
G

Gnarlodious

I'm doing that:
import Module.Data as Data

However I end up doing it in every submodule, so it seems a little
redundant. I wish I could load the variable in the parent program and
have it be available in all submodules. Am I missing something?

-- Gnarlie
 
P

Peter Otten

Gnarlodious said:
I'm doing that:
import Module.Data as Data

from Module import Data

There, you saved three more characters .
However I end up doing it in every submodule, so it seems a little
redundant. I wish I could load the variable in the parent program and
have it be available in all submodules. Am I missing something?

You can modify the builtin namespace:

$ cat module.py
print data
$ cat main.py
import __builtin__
__builtin__.data = 42

import module
$ python main.py
42
$

But I don't think it's a good idea. Remember that "explicit is better than
implicit".
 
N

Noah Hall

I'm doing that:
import Module.Data as Data

Well, that's not quite the same. You're using Module.Data as Data - I
guess you've done this because you've realised that import Module
means you still have to write Module.Data every time. But the correct
way to is state exactly which function or object you want - for
example, from Module import Data. Simple, right? I mean, you almost
had it, but it seems like you've gotten a little confused with various
theories.

However I end up doing it in every submodule, so it seems a little
redundant. I wish I could load the variable in the parent program and
have it be available in all submodules. Am I missing something?

Well, generally, if you've got a variable that you need in all your
sub-modules, the chances are that your code infrastructure needs a bit
of reordering (at least, that's what I find in my case). Without
seeing your code, though, I would find it hard to make a judgement on
what you need. Perhaps reading up on the documentation will help -
http://docs.python.org/tutorial/modules.html#packages

Noah.
 
B

bruno.desthuilliers

You can modify the builtin namespace:
But I don't think it's a good idea.

Even posting about it is already a bad idea IMHO. There are good
reasons this isn't documented.

@OP: yes, explicit imports are boring... until you have to debug and
maintain the code, and then you start to LOVE them.
 
G

Guillaume Martel-Genest

Is there a way to declare a project-wide variable and use that in all
downstream modules?

-- Gnarlir

What about using an environment variable?
 
G

Gnarlodious

Yes, that's fine, but only if the data is suitable for it.

In this case, the variable is a namespace containing the property of a
folder full of plist files. I access any dictionary item anywhere in
my webapp with a namespace like this:

Data.Plist.SectrumDB.Sectrum.Contents.Character.Type
Unicode string

There are hundreds of these dictionary items in the namespace, and it
has been a powerful programming tool. I simply wonder if there is a
more elegant way of giving my entire application access to these
variables from the top. Apparently not, from what I gather.

-- Gnarlie
http://Gnarlodious.com
 
T

Terry Reedy

I'm doing that:
import Module.Data as Data

However I end up doing it in every submodule, so it seems a little
redundant. I wish I could load the variable in the parent program and
have it be available in all submodules. Am I missing something?

Yes. Make a project ~template.py file that includes the common import.
Mine is something like

#!python3
'''project_dir/.py -- 2011
Copyright Terry Jan Reedy

'''
from test import ftest,itest


def test_main():


if __name__ == '__main__':
test_main()
 
S

Steven D'Aprano

I don't understand this. Can you explain, or refer me to some
documentation?

What part don't you understand?

This is Terry's template. It's not meant to work as-is, he has to fill in
the details, such as what test_main() actually does.

The "if __name__ == '__main__'" idiom is a common way of making a Python
script. When you import a module, Python automatically adds a global to
it called __name__, and sets it to the name of the module. E.g.:
'math'

When you run a module as a script, Python sets the __name__ to '__main__'
instead. So this is a (slightly hacky) way of distinguishing code that
runs when the module is imported from code that runs on execution.
 
G

Gnarlodious

Let me restate my question.
Say I have a script Executable.py that calls all other scripts and
controls them:

#!/usr/local/bin/python
from Module import Data
import ModuleTest

ModuleTest.py has this:

print(Data.Plist.Structure)

Running Executable.py gives me this:
NameError: name 'Data' is not defined

1) Can I tell Executable.py to share Data with ModuleTest.py?
or if that can't be done:
2) Can I tell ModuleTest.py to "look upstream" for Data?

I have used two systems to accomplish this purpose:
1) Import Data into every module as it is loaded, which I am doing
now, and:
2) Load Data at the top and pass it downstream as a variable. This
gets a little cluttered and I quit doing it that way.

So I am looking for an easier way to load Data as an application-wide
variable. If its impossible to do what I want, I can accept that.

-- Gnarlie
 
G

Gnarlodious

Idea: It occurs to me that my application class inherits "object". Can
I set that to inherit an object that already includes data? So every
subsequent class would start off with data loaded (except for class
Data).

Seems like it should already be invented.

-- Gnarlie
 
A

alex23

Seems like it should already be invented.

If you're finding you're importing the same data into every single
module, then you're doing something wrong. Creating dependencies
across modules like you're wanting is a recipe for suffering.
 
T

Terry Reedy

Let me restate my question.
Say I have a script Executable.py that calls all other scripts and
controls them:

#!/usr/local/bin/python
from Module import Data
import ModuleTest

ModuleTest.py has this:

print(Data.Plist.Structure)

Running Executable.py gives me this:
NameError: name 'Data' is not defined

1) Can I tell Executable.py to share Data with ModuleTest.py?

After the import is complete, yes.
import ModuleTest
ModuleTest.Data = Data

This works if the use of Data is inside a function that is not called
during import, not if the use of Data is at toplevel or in a class
statement outside a def.
or if that can't be done:
2) Can I tell ModuleTest.py to "look upstream" for Data?

Yes if ModuleTest imports Executable, but circular imports are a bad idea.
 
G

Gnarlodious

After the import is complete, yes.
import ModuleTest
ModuleTest.Data = Data

This works if the use of Data is inside a function that is not called
during import, not if the use of Data is at toplevel or in a class
statement outside a def.

That works! The solution looks like this:

# controlling program:
from Module import Data
import ModuleTest
ModuleTest.Data = Data
ModuleTest.getData()

# module:
def getData():
print(Data.Plist.Structure)


Thanks for all your help!

-- Gnarlie
 
T

Terry Reedy

That works! The solution looks like this:

# controlling program:
from Module import Data
import ModuleTest
ModuleTest.Data = Data
ModuleTest.getData()

# module:
def getData():
print(Data.Plist.Structure)

This is a form of dependency injection, where a caller injects into a
callee a dependency (callee) of the callee. It can be used even if the
callee imports a dependency when it is imported. It is useful for
testing when you want the callee to use a different dependency for
testing. Simple example:

# MyModule
import socket
def myconnect(*args):
... socket.bind()

# Test_MyModule
import mock_socket
import MyModule
MyModule.socket = mock_socket
.... test of MyModule, including MyModule.myconnect

Python makes this trivial without requiring that the otherwise constant
depedency always be injected or passed (in normal production use) as a
variable.

In your case, you are free to inject different forms of Data if you wish.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,160
Messages
2,570,889
Members
47,421
Latest member
StacyTaver

Latest Threads

Top