Let's say this is my class:
class A:
def __init__(self):
self.good_attr = None
self.really_good_attr = None
self.another_good_attr = None
Then a caller can set the values on those variables:
a = A()
a.good_attr = 'a value'
a.really_good_attr = 'better value'
a.another_good_attr = 'a good value'
But they can also add new attributes:
a.goood_value = 'evil'
This is not desirable for my use case. My object is being used to pass a number of values into a set of methods. (So essentially, this object replaces a long list of shared parameters on a few methods to avoid duplication and clearly distinguish what's shared and what's different.) If a caller typos an attribute name, then the attribute would just be ignored, resulting in unexpected and confusing and potentially hard to figure out behavior. It would be better to fail fast, notifying the caller that they used an attribute name that will be ignored. So something similar to the following is the behavior I would like when they use an attribute name that doesn't already exist on the object:
>>> a.goood_value = 'evil'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute 'goood_value'
How can I achieve this?
I would also like to note that I'm fully aware that a caller can create a new class and do whatever they want, bypassing this entirely. This would be unsupported behavior, though. Making the object I do provide just creates a fail-fast bonehead check to save time against typos for those who do leverage the object I'm providing (myself included), rather than making them scratch their heads wondering why things are behaving in unexpected ways.