Классы httplib.HTTPMessage
и email.message.Message
[1] реализуют методы синтаксического анализа заголовков RFC822.К сожалению, они имеют разные реализации [2] и не обеспечивают одинаковый уровень функциональности.
Один из примеров, который меня беспокоит, это то, что:
httplib.HTTPMessage
отсутствует метод get_filename
, присутствующий в email.Message
, который позволяет легко извлечь имя файла из заголовка Content-disposition: attachment; filename="fghi.xyz"
;
httplib.HTTPMessage
имеет getparam
, getplist
и parseplist
методы, но AFAIK, они не используются и не могут использоваться вне синтаксического анализа заголовка content-type
;
email.Message
имеет универсальный метод get_param
для анализа любогоЗаголовок RFC822 с параметрами, такими как content-disposition
или content-type
.
Таким образом, я хочу, чтобы get_filename
или get_param
методы email.message.Message
в httplib.HTTPMessage
, но,конечно, я не могу исправить httplib.HTTPMessage
, как в стандартной библиотеке ...: -q
И, наконец, вот тема декоратора ...: -)
Iуспешно создал 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
имеет собственную реализацию.