Reputation: 44395
In my problem I have a python code that is being started by a user, like:
# file main.py
import sys
import mymodule
config = sys.argv[1]
which imports another module containing functions, classes etc. like
# module.py
def check_config():
# do something with the content of 'config'
class Module(object):
# does something with the content of 'config'
How can I access the value of 'config' from within module.py
? Should I use a 'global' variable here? Or is there a more sophisticated, pythonic way to solve this problem?
Also, I do not want to define an argument 'config' to each function and class I use in other modules...
Further remark: main.py
imports other modules, not the other way around...
Upvotes: 3
Views: 785
Reputation: 9969
Instead of trying to wrangle global
into performing this you should pass config
as a parameter.
import sys
import mymodule
config = sys.argv[1]
checked = mymodule.check_config(config)
mod = mymodule.Module(config)
def check_config(config):
# do something with the content of 'config'
class Module(object):
# does something with the content of 'config'
def __init__(self, config):
# initialise with config
Always avoid usingglobal
when you can. If you need to modify config
just have a module function return it.
config = change_config(config)
def change_config(config):
...
return config
However, an alternative method is to define a value within module.py
which will store this information that holds nothing by default. Then as soon as file main.py
has imported module.py
and the config data is ready, you could assign the data to module.py
's config name. Like this:
import sys
import mymodule
config = sys.argv[1]
mymodule.config = config
mymodule.test_config()
mymodule.check_config()
mymodule.Module()
config = None
def test_config():
print config
# this will refer to the value supplied from file main.py
Note however, that the values in the module and main file will not be joined. If you reassign config in file main.py
for any reason you have to pass that value to the module again. However if you pass a mutable value like a dict or list then you can modify it in file main.py
and the values will be shared.
Upvotes: 3
Reputation: 532238
I don't recommend using a global variable, but here's the design you should use if you do. config
needs to be defined in mymodule
; after you import the module, you can set the value of mymodule.config
the way you are currently setting config
.
# file main.py
import sys
import mymodule
mymodule.config = sys.argv[1]
# module.py
# The exact value doesn't matter, as long as we create the name.
# None is good as it conveys the lack of a value; it's part of your
# module's contract, presumably, that a proper value must be assigned
# before you can use the rest of the module.
config = None
def check_config():
# do something with the content of 'config'
class Module(object):
# does something with the content of 'config'
Upvotes: 2
Reputation: 3919
Could you describe that you app should to do? Because now it's not clear, why you want it. Maybe environment variable could help you?
Btw, you can read config file in one place (module), and import all stuff you need from it.
config.py
import os
if os.environ['sys'] == 'load_1':
import load_1 as load
i = 12
else:
import load_2 as load
i = 13
main.py
import config
config.load("some_data")
print config.i
Upvotes: 0
Reputation: 169
A global variable is almost never the answer. Just allow the functions and classes in your "library" (module.py
or mymodule.py
, you seem to use both) to accept arguments. So:
mymodule.py
def check_config(configuration):
pass
class Module(object):
def __init__(self, configuration):
self.config = configuration
class ConfigError(Exception):
pass
Then when you want to use them in your "application" code:
main.py
import sys
import mymodule
config = sys.argv[1]
if mymodule.check_config(config):
myobject = mymodule.Module(config)
else:
raise mymodule.ConfigError('Unrecognized configuration format.')
Upvotes: 1