httplib.HTTPMessage
およびemail.message.Message
classes[1]は、RFC822ヘッダー解析のメソッドを実装します。残念ながら、それらには異なる実装があり[2]、同じレベルの機能を提供していません。
私を悩ませている1つの例はそれです:
httplib.HTTPMessage
に存在するget_filename
メソッドがありません。これにより、ヘッダーemail.Message
からファイル名を簡単に取得できます。Content-disposition: attachment; filename="fghi.xyz"
httplib.HTTPMessage
getparam
、getplist
およびメソッドがありますが、AFAIKですが、ヘッダー解析parseplist
の外部では使用できません。content-type
email.Message
またはget_param
などのパラメータを使用してRFC822ヘッダーを解析する一般的なメソッドがあります。content-disposition
content-type
したがって、get_filename
またはget_param
のメソッドが必要email.message.Message
です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)
私は今頭を悩ませています...文字通りソースメソッドをコピーせずにクラスを装飾するにはどうすればよいですか?
助言がありますか ?:-)
よろしく、
ジョージ・マーティン
Python2.6の場合。本番環境では2.7も3.xも使用できません。
httplib.HTTPMessage
から継承しmimetools.Message
、独自の実装がありますrfc822.Message
。email.Message