So lets say I have a class called Car
as below:
class Car(object):
"""Car example with weight and speed."""
def __init__(self):
self.weight = None
self.speed = None
If I initialize a Car
as an empty object:
red_car = Car()
And I add a speed
and a weight
:
red_car.speed = 60
red_car.weight = 3500
That's all fine but what if I want to run a function when attempting to add those variables to the instance? Like this function:
def change_weight(self, any_int):
return (any_int - 10)
The thing is though I want it to automatically run this function whenever I attempt to add specific instance variables to the object. If possible I would like it to run change_weight
only on the weight
instance variable.
Am I understanding this correctly or should I just be running the integer through the function separately and then adding to the object after manually?
You want to use properties
class Car(object):
"""Car example with weight and speed."""
def __init__(self):
self._weight = None # internal value
self.speed = None
@property
def weight(self):
return self._weight
@weight.setter
def weight(self, the_weight):
self._weight = the_weight - 10 # or whatever here
Now, you can set speed
normally; when you execute car.weight = 20
the setter function will be called, and the actual weight will be set to 20 - 10 = 10
.
Read up on Python's notion of Descriptors. In particular, it sounds like you want to define a custom __set__()
method.
For example, obj.d
looks up d
in the dictionary of obj
. If d
defines the method__get__()
, then d.__get__(obj)
is invoked according to the precedence rules listed below.
Alternately, you may find using Properties
(a specific type of Descriptor) a little easier to work with.
property()
is a succinct way of building a data descriptor that triggers function calls upon access to an attribute.
The behavior of descriptors is fairly logical once you understand it, but it doesn't behave quite as you might expect; in particular, __get__()
and __set__()
should not be confused with getters and setters, like the Java concept. So look at some of the examples above and play around with them before diving in.