httplib.HTTPMessage
和email.message.Message
类[1]实现了RFC822标头解析的方法。不幸的是,他们有不同的实现[2],他们不提供相同级别的功能。被窃听我如何用另一个类的方法来装饰(monkeypatch ...)一个Python类?
一个例子是:
httplib.HTTPMessage
缺少get_filename
方法存在于email.Message
,即让您轻松检索来自Content-disposition: attachment; filename="fghi.xyz"
头的文件名;httplib.HTTPMessage
具有getparam
,getplist
和parseplist
方法,但AFAIK,它们不和不能在content-type
报头解析外部使用;email.Message
有一个通用的get_param
方法来解析与参数,如content-disposition
或content-type
任何RFC822报头。
因此,我想的email.message.Message
的get_filename
或get_param
方法httplib.HTTPMessage
但是,当然,我不能修补httplib.HTTPMessage
,因为它是在标准库...:-q
最后,来这里的装饰主题... :-)
我成功地创建了一个monkeypatch_http_message
功能来装饰我缺少分析方法的httplib.HTTPMessage
:
def monkeypatch_http_message(obj):
from email import utils
from email.message import (
_parseparam,
_unquotevalue,
)
cls = obj.__class__
# methods **copied** from email.message.Message source code
def _get_params_preserve(self, failobj, header): ...
def get_params(self, failobj=None, header='content-type',
unquote=True): ...
def get_param(self, param, failobj=None, header='content-type',
unquote=True): ...
def get_filename(self, failobj=None): ...
# monkeypatching httplib.Message
cls._get_params_preserve = _get_params_preserve
cls.get_params = get_params
cls.get_param = get_param
cls.get_filename = get_filename
现在我可以这样做:
import mechanize
from some.module import monkeypatch_http_message
browser = mechanize.Browser()
# in that form, browser.retrieve returns a temporary filename
# and an httplib.HTTPMessage instance
(tmp_filename, headers) = browser.retrieve(someurl)
# monkeypatch the httplib.HTTPMessage instance
monkeypatch_http_message(headers)
# yeah... my original filename, finally
filename = headers.get_filename()
这里的问题是,我从字面上源类,我想避免复制装饰方法的代码。
所以,我想通过引用源装饰方法:
def monkeypatch_http_message(obj):
from email import utils
from email.message import (
_parseparam,
_unquotevalue,
Message # XXX added
)
cls = obj.__class__
# monkeypatching httplib.Message
cls._get_params_preserve = Message._get_params_preserve
cls.get_params = Message.get_params
cls.get_param = Message.get_param
cls.get_filename = Message.get_filename
但是,这给了我:
Traceback (most recent call last):
File "client.py", line 224, in <module>
filename = headers.get_filename()
TypeError: unbound method get_filename() must be called with Message instance as first argument (got nothing instead)
现在我抓我的头......我怎么能装点我的课没有从字面上复制源方法?
有什么建议吗? :-)
问候,
乔治·马丁
在Python 2.6。我不能在生产中使用2.7或3.x。
httplib.HTTPMessage
继承自mimetools.Message
和rfc822.Message
而email.Message
有它自己的实现。
Waaaaaay干净多了:-) 高清monkeypatch_http_message(OBJ): 进口httplib的 断言isinstance(OBJ,httplib.HTTPMessage) CLS =的obj .__ class__ 从电子邮件进口utils的 从email.message进口(_parseparam,_unquotevalue,消息) funcnames =( '_get_params_preserve', 'get_params', 'get_param', 'get_filename') 为funcname的在funcnames: CLS .__字典__ [funcname的] =消息.__字典__ [funcname的] 谢谢! :-) – 2011-02-25 09:01:53