Reputation: 810
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
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
Reputation: 1484
You could try making a single list parameter for each function, if that makes it easier.
Upvotes: 0