Q:

Safe attribute asignment in python

I have a class representing parameter options for my algorithm.  Creating an object initializes all options to some predefined values.  I can then change a parameter by simply assigning a different value to the corresponding attribute:
opts = AlgOptions()
opts.mutation_strength = 0.2

However, I sometimes make a mistake when typing the attribute name, for example:
opts = AlgOptions()
opts.mutation_str = 0.2

Python just creates a different attribute and continues running, producing unexpected results which are difficult to debug. 
Is there an elegant way to avoid this potential pitfall?  It feels tedious to always double check all attribute names, compared to languages such as C# which would interpret this situation as an error.  Few things come to my mind, but have some caveats:
1) I can make setter methods for parameters, but that seems like a lot of boilerplate code.  That way if I try to invoke a method with a wrong name, I will get a meaningful excepion. 
2) I can create a list of all attributes inside the class, and perform a check if there is any class attribute whose name is not in the list.  However, I am not sure where and when would I perform the check, and it seems like a clumsy solution anyway. 

A:

You can achieve this by using slots, which basically prevents creating of attributes not declared in __init__:
>>> class Foo:
...     __slots__ = ["bar", "baz"]
...     def __init__(self, bar, baz):
...         self.bar = bar
...         self.baz = baz
...
>>> foo = Foo(1, 2)
>>> foo.asdf = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute 'asdf'
>>> foo.bar
1
>>> foo.bar += 5
>>> foo.bar
6

Note that using __slots__ has some disadvantages discussed in the documentation.