Thomas Schreiter
Thomas Schreiter

Reputation: 810

Python: How to set up configuration variables of program?

I'm writing a script that takes a directory as input. This directory will be used by many different functions which read data from the disk. Currently, the directory name is stored in a variable, which is passed through to each function or class that uses it:

data_dir = get_data_dir()
spam = calculate_spam(foo, bar, data_directory=data_dir)
eggs = calculate_eggs(spam, baz, data_directory=data_dir)

Unfortunately, the function signatures and function calls get quite long, which makes the code unnecessarily hard to read and therefore error-prone. Is there a better (i.e. Pythonic) way handling configuration parameters like this?

Upvotes: 2

Views: 155

Answers (2)

jme
jme

Reputation: 20695

If you have a bunch of functions who share many required arguments, such as:

foo(x, y, z, alpha)
bar(x, y, z, beta)
baz(x, y, z, gamma)

It can be a sign that x, y, and z belong in a dictionary or namedtuple together. You might go this route and place the parts of your configuration that go together into a namedtuple. But note that you generally only want to pass exactly what is needed into a function, and no more. So if your functions are taking a dictionary with a bunch of configuration parameters just to use a single entry, it might be a sign of bad design.

It might even make sense to put x, y, and z in a class, and make foo, bar, and baz methods:

class XYZ:

    def __init__(self, x, y, z):
        ...

    def foo(self, alpha):
        ...

    def bar(self, beta):
        ...

    def baz(self, gamma):
        ...

The configuration then becomes part of the state of your class.

On the other hand, long argument lists can be a sign that your function does more than it needs to. Consider your function, calculate_spam(foo, bar, data_dir). Presumably, this function loads some data from a directory and computes some data. Would it make more sense to separate the loading and the computing into two separate functions, such as load_spam(data_dir) to load the data, then calculate_spam(data, ...) to calculate it?

I often find that when I have too many arguments, I just need to split the function into smaller pieces. It's not a law, but a rule of thumb that works a lot of the time for me.

Upvotes: 2

Academiphile
Academiphile

Reputation: 1484

You could try making a single list parameter for each function, if that makes it easier.

Upvotes: 0

Related Questions