Python:替换日历模块中的方法

2 投票
3 回答
1415 浏览
提问于 2025-04-16 04:52

我正在尝试替换日历模块中的两个方法:

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_formatweek

print c.formatmonth(2012,1,"foobar")

这样做是不行的——有人能告诉我相关的资料或者指出我哪里做错了吗?我想实现Alan Hynes在以下讨论中提到的建议:讨论。现在已经很晚了,我脑子有点转不过来,已经在这个问题上纠结了一个多小时。

提前谢谢你们,
Jakub

3 个回答

1

试着在类里面替换这个方法,而不是在实例里面。

像这样:

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")                                                                            
1

更新:根据评论中Aaron的建议,使用了types.MethodType

试试这个:

import types
c.formatday = types.MethodType(ext_formatday, c, calendar.HTMLCalendar)

可以查看一下types模块的文档,了解为什么之前会出错:

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'
0

你不想直接替换这些方法;Alan Hynes 建议你去 子类化 HTMLCalendar:

class MyCustomCalendar(calendar.HTMLCalendar):

    def formatday(self, day, weekday, *notes):
        ...

    def formatweek(self, theweek, *notes):
        ...

c = MyCustomCalendar(calendar.MONDAY)

这样做会创建一个新的派生类(MyCustomCalendar),它会继承 HTMLCalendar 的所有方法和属性,但可以定义自己版本的 formatdayformatweek 方法。

你可以在 Python 教程 或其他网站上了解更多关于 继承 的内容。这是 Python(以及面向对象编程)中的一个重要工具,很多库都是围绕它设计的。

撰写回答