Python allows you to assign a pre-defined function to a class as an attribute, such as
def fish_slap(fish):
# do something
class dance(object):
dance_move=fish_slap
However, if we try do say
d=dance()
d.dance_move("Halibut")
we get the get the following error
TypeError: fish_slap() takes exactly 1 arguement (2 given)
Python seems to be viewing this as a object method and providing the implied 'self' argument. Fair enough, it seems I've just learned that assigning a function as an attribute in this way is equivalent to defining the function directly within the class. I can see that this is a useful feature.
However, in this case this is not what I want. In my application I have statistical models encoded as different classes which also have their own 'train' methods for training the model parameters against supplied data. In order to do this, an objective function that you wish to minimize (or maximize) the value of needs to be supplied. An example simple objective function is say
def RMSE(predicted,observed):
"Root mean squared error"
return sp.sqrt(sp.mean((predicted-observed)**2))
where SciPy has been imported as sp. These objective functions are defined in a single .py file and used throughout my code and naturally exists as standalone functions, rather than as class methods with the implied 'self' argument.
I want to be able to set the desired objective function as an attribute so that any subsequent work a model object does uses that function, for instance
some_model=SomeModel(initial_parameter_values_guess)
some_model.objective_function = RMSE
some_model.train(training_data)
predictions_RMSE = some_model.predict()
some_mode.objective_function = MAE
predictions_MAE = some_model.predict()
In this example is seems I could just pass the objective function as an argument to train, however in my application there is a lot more one would want to do and it seems to make more sense to be able to set/get the objective function rather than repeatedly providing it as an argument.
There are any number of workarounds to achieve this basic behavior, but what is the most pthonic approach?
Note that my current code is python2 and python3 compliant. If there are version specific solutions please point that out. I am running with python2 in order to be able to use matplotlib however I am trying to ensure the code is python3 compatible apart from that module.
7.1. In the case of no arguments and no return value, the definition is very simple. Calling the function is performed by using the call operator () after the name of the function.
If there was no self argument, the same class couldn't hold the information for both these objects. However, since the class is just a blueprint, self allows access to the attributes and methods of each object in python. This allows each object to have its own attributes and methods.
self represents the instance of the class. By using the “self” we can access the attributes and methods of the class in python. It binds the attributes with the given arguments. The reason you need to use self. is because Python does not use the @ syntax to refer to instance attributes.
while you can access class attributes using an instance it's not safe to do so. In python, the instance of a class is referred to by the keyword self. Using this keyword you can access not only all instance attributes but also the class attributes.
You can use a staticmethod
class dance(object):
dance_move=staticmethod(fish_slap)
Note that you don't need to use staticmethod
if you're assigning to an attribute of an instance:
>>> def move():
... print "disco party!"
...
>>> class dance(object):
... dance_move = staticmethod(move)
...
>>> d = dance()
>>> d.dance_move()
disco party!
>>> d.break_it_down = move
>>> d.break_it_down()
disco party!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With