I'm designing an API for a Python library. The user will create objects with several parameters. In most cases, the user will either leave these at their default values or will set them globally, for all objects. However, it should be possible also to set them individually on a per-object basis.
The most obvious way to do this is to do something like this:
# myModule.py
contrafibularity_threshold = 10.7
pericombobulation_index = 9
compunctuous_mode = False
class Thing:
def __init__(self):
self.contrafibularity_threshold = None
pericombobulation_index = None
compunctuous_mode = None
def get_contrafibularity_threshold(self):
if self.contrafibularity_threshold is not None:
return self.contrafibularity_threshold
else:
return contrafibularity_threshold
def get_pericombobulation_index(self):
if self.pericombobulation_index is not None:
return self.pericombobulation_index
else:
return pericombobulation_index
def get_compunctuous_mode(self):
if self.compunctuous_mode is not None:
return self.compunctuous_mode
else:
return compunctuous_mode
This works as I would like: it allows the user to do myModule.contrafibularity_threshold = 10.9
to set the global value while also being able to do someThing.contrafibularity_threshold = 11.1
to set it for a particular object. The default may be changed at any time and will affect only those objects to which a specific value has not been assigned.
However, the code above contains a lot of repetition, and seems prone to hard-to-notice bugs if I make a mistake copy-pasting the code. Is there a better (less repetitive, less error-prone, more Pythonic) way to achieve these goals? I don't mind changing the API, as long as the user can change the defaults at both the global and per-object level.
(One could arguably improve the above code by using @property
, but that wouldn't resolve the repetitive code issue.)