Nickpick
Nickpick

Reputation: 6587

Conserving a state in a large python program without passing variable as parameter

I have a large project where I load in some variables from a config.ini, such as the target_directory of the data that is generated. This target_directory is used all over the project but it is not always set in the same place. It can be set by config.ini, but it can be overridden by command line parameters or also by unit tests.

What is the best way to preserve that state in a global way, so I don't have to pass it into every function of my program.

The program consists of many different modules and packages and I was wondering if there's a best practice how this could be handled.

Upvotes: 1

Views: 83

Answers (2)

stavxyz
stavxyz

Reputation: 2025

You could set state into a module-level variable using a dictionary, or any other type of container. These values are not static, and can be modified/mutated by any code that has access to them (unless you use an immutable container, like a tuple or namedtuple). You can import the whole conf.py module with import conf, or just pull in the configuration container with from conf import CONFIG

# this is conf.py

import argparse
import configparser

CONFIG = {}

def build_config():
    # ...compose your config from cli, ini file, etc
    CONFIG['option_one'] = 'hello world'
    return CONFIG

...

# this is a.py
import conf

def do_something_with_config_value():
    return conf.CONFIG['option_one']

...

# this is b.py

import a
import conf

if __name__ == '__main__':
    conf.build_config()
    print(a.do_something_with_config_value())

Upvotes: 2

Nickpick
Nickpick

Reputation: 6587

This seems to work:

main.py

import c2
from c3 import func

c2.v1 = 1
c2.v2 = 1
c2.v3 = 1


def edit():
    c2.v1 = 11

if __name__ == "__main__":
    edit()
    func()

c2.py (the configuration container)

v1 = 2
v2 = 2

c3.py

import c2

def func():
    print (c2.v1)
    print (c2.v2)
    print (c2.v3)

output:

11
1
1

Upvotes: 0

Related Questions