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.)