开发者

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">&nbsp;</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,

Jakub


Try 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">&nbsp;</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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜