Python: replacing method in calendar module
I'm trying to replace two methods in calendar module:
import calendar
c = calendar.HTMLCalendar(calendar.MONDAY)
def ext_formatday(self, day, weekday, *notes):
if day == 0:
return '<td class="noday"> </td>'
if len(notes) == 0:
return '<td class="%s">%d<br /></td>' % (self.cssclasses[weekday], day)
else:
return '<td class="%s">%d<br />%s</td>' % (self.cssclasses[weekday], day, notes)
def ext_formatweek(self, theweek, *notes):
if len(notes) == 0:
s = ''.join(self.formatday(d, wd) for (d, wd) in theweek)
else:
s = ''.join(self.formatday(d, wd, notes) for (d, wd) in theweek)
return '<tr>%s</tr>' % s
c.formatday = ext_formatday
c.formatweek = ext开发者_C百科_formatweek
print c.formatmonth(2012,1,"foobar")
This won't work - could somebody point me to relevant literature or point out what I'm doing wrong? I'm trying to implement Alan Hynes suggestion from the following thread: thread It way too late for me to think straight and I've been dancing around that problem for over an hour.
Thanks in advance,
JakubTry replacing the method at the class instead of the instance.
Like this:
import calendar
def ext_formatday(self, day, weekday, *notes):
if day == 0:
return '<td class="noday"> </td>'
if len(notes) == 0:
return '<td class="%s">%d<br /></td>' % (self.cssclasses[weekday], day)
else:
return '<td class="%s">%d<br />%s</td>' % (self.cssclasses[weekday], day, notes)
def ext_formatweek(self, theweek, *notes):
if len(notes) == 0:
s = ''.join(self.formatday(d, wd) for (d, wd) in theweek)
else:
s = ''.join(self.formatday(d, wd, notes) for (d, wd) in theweek)
return '<tr>%s</tr>' % s
calendar.HTMLCalendar.formatday = ext_formatday
calendar.HTMLCalendar.formatweek = ext_formatweek
c = calendar.HTMLCalendar(calendar.MONDAY)
print c.formatmonth(2012,1,"foobar")
Updated to use types.MethodType
as suggested by Aaron in the comments.
Try:
import types
c.formatday = types.MethodType(ext_formatday, c, calendar.HTMLCalendar)
See the types module docs. To see why it was failing:
In [53]: class A(object):
....: def foo(self): pass
In [54]: def bar(self): pass
In [55]: a = A()
In [56]: a.foo
Out[56]: <bound method A.foo of <__main__.A object at 0x030D4770>>
In [57]: a.foo = bar
In [58]: a.foo
Out[58]: <function bar at 0x030C3EB0>
In [59]: aa = A()
In [60]: aa.foo.im_class, aa.foo.im_func, aa.foo.im_self
Out[60]:
(<class '__main__.A'>,
<function foo at 0x030EE6F0>,
<__main__.A object at 0x030D4910>)
In [61]: a.foo.im_class
AttributeError: 'function' object has no attribute 'im_class'
You don't want to replace the methods; what Alan Hynes suggested was to subclass HTMLCalendar:
class MyCustomCalendar(calendar.HTMLCalendar):
def formatday(self, day, weekday, *notes):
...
def formatweek(self, theweek, *notes):
...
c = MyCustomCalendar(calendar.MONDAY)
This will create a new derived class (MyCustomCalendar), which inherits all HTMLCalendar's methods and attributes, but defines its own versions of formatday
and formatweek
.
You can read more about Inheritance in the Python tutorial, or elsewhere on the web. It's an important tool in Python (and object-oriented programming in general), and many libraries are designed around it.
精彩评论