The arguments passed to setCustAttr
are exactly the arguments you would pass to setattr
.
def setCustAttr(self, name, value):
setattr(self, name, value)
Why would you want a wrapper around setattr
? You might try to perform some validation:
def setCustAttr(self, name, value):
if name not in ['bar', 'baz']:
raise ValueError("Custom attribute must be 'bar' or 'baz'")
if name == 'bar' and value < 0:
raise ValueError("'bar' attribute must be non-negative")
if name == 'baz' and value % 2:
raise ValueError("'baz' attribute must be even")
setattr(self, name, value)
However, this doesn't prevent the user of your class from ignoring your setCustAttr
method and assigning directly to the object:
g = MyClass()
g.bar = -5 # Negative bar!
g.baz = 3 # Odd baz!
g.quux = 2 # Non-bar/baz attribute!
Python has deep magic for providing more control over how attributes are set on an object (see __slots__
, __{get,set}attr__
, __getattribute__
, properties, etc), but generally, they aren't used merely to prevent the examples shown above. The Python way is to just document how an instance of your class should be used, and trust the user to abide by your instructions. (And if they don't, caveat emptor.)