Reputation: 1654
Sorry for the clumsy title of the question but I can't think of a suitable way to express it. I am working on a calendar-type application in Python 2.7. I have a class Day
which has a constructor of the form
def __init__(self, d):
# Date in datetime.date format
self.date = d
# Julian date
self.julian = date_utils.calendar_util.gregorian_to_jd(d.year, d.month, d.day)
# Sun and moon rise and set times
self.sun = RiseSet()
self.moon = RiseSet()
...
def SetSunRise(self, t):
assert type(t) is datetime.time
self.sun.rise = t
def SetSunSet(self, t):
assert type(t) is datetime.time
self.sun.set = t
where RiseSet
is a simple class:
def __init__(self, r=None, s=None):
# rise (r) and set (s) times should normally be datetime.time types
# but it is possible for there to
# be no sun/moon rise/set on a particular day so None is also valid.
if r is not None:
assert type(r) is datetime.time
if s is not None:
assert type(s) is datetime.time
if r is not None and s is not None:
assert r < s
self.rise = r
self.set = s
Obviously there is a Day
object for each day in a particular calendar. These are contained in a dictionary (keyed on datetime.date
) called days
. Now I have four lists containing the sun/moon rise/set times for the period in question: sunrises
, sunsets
, moonrises
, moonsets
and want to set the sun/moon rise/set times for each Day
in days
.
Now I could just have four separate loops going through each of the four lists. But what I really want to do is effectively use something like a pointer to a function so I could have something like:
for (func, obj) in zip([Day.SetSunRise, Day.SetSunSet, Day.SetMoonRise, Day.SetMoonSet], [sunrises, sunsets, moonrises, moonsets])
So effectively what I'm trying to do is get a pointer to a function but based on the class definition not the individual object/instance of that class. I'm sure there must be some simple, elegant way to do this but I am currently stumped.
Anybody?
Upvotes: 0
Views: 70
Reputation: 1123410
You are almost there. You can do just that, refer to the unbound method on the Day
class, then pass in an instance to invoke that method.
In other words: Day.SetSunRise
is a reference to an unbound method waiting for you to call it with a Day()
instance:
someday = Day()
Day.SetSunRise(someday, some_sunrise_time)
Unbound methods, like functions, are objects and you can store them in lists, etc:
for meth, timestamp in zip([Day.SetSunRise, Day.SetSunSet], [sunrise, sunset]):
meth(someday, timestamp)
Now all you need to do is loop over your sunsets, your sunrises, etc. zip those up (or otherwise combine them) with their matching Day
instances and for you to call the method.
Upvotes: 1