I'd like to do something like this:
class SillyWalk(object):
@staticmethod
def is_silly_enough(walk):
return (False, "It's never silly enough")
def walk(self, appraisal_method=is_silly_enough):
self.do_stuff()
(was_good_enough, reason) = appraisal_method(self)
if not was_good_enough:
self.execute_self_modifying_code(reason)
return appraisal_method
def do_stuff(self):
pass
def execute_self_modifying_code(self, problem):
from __future__ import deepjuju
deepjuju.kiss_booboo_better(self, problem)
with the idea being that someone can do
>>> silly_walk = SillyWalk()
>>> appraise = walk()
>>> is_good_walk = appraise(silly_walk)
and also get some magical machine learning happening; this last bit is not of particular interest to me, it was just the first thing that occurred to me as a way to exemplify the use of the static method in both an in-function context and from the caller's perspective.
Anyway, this doesn't work, because is_silly_enough
is not actually a function: it is an object whose __get__
method will return the original is_silly_enough
function. This means that it only works in the "normal" way when it's referenced as an object attribute. The object in question is created by the staticmethod()
function that the decorator puts in between SillyWalk
's is_silly_enough
attribute and the function that's originally defined with that name.
This means that in order to use the default value of appraisal_method
from within either SillyWalk.walk
or its caller, we have to either
- call
appraisal_method.__get__(instance, owner)(...)
instead of just callingappraisal_method(...)
- or assign it as the attribute of some object, then reference that object property as a method that we call as we would call
appraisal_method
.
Given that neither of these solutions seem particularly Pythonic™, I'm wondering if there is perhaps a better way to get this sort of functionality. I essentially want a way to specify that a method should, by default, use a particular class or static method defined within the scope of the same class to carry out some portion of its daily routine.
I'd prefer not to use None
, because I'd like to allow None
to convey the message that that particular function should not be called. I guess I could use some other value, like False
or NotImplemented
, but it seems a) hackety b) annoying to have to write an extra couple of lines of code, as well as otherwise-redundant documentation, for something that seems like it could be expressed quite succinctly as a default parameter.
What's the best way to do this?