3

python3.3 で導入された新しい smtplib 機能に興味があります:マルチホームマシン (または複数の IP アドレスを持つマシン) で特定の IP アドレスにバインドする機能です。

私が使用したい多くのビルディング ブロックは 3.3 に移植されていないか、ポートが非常に不安定であるため、この機能のためだけに 3.3 を使用するという考えは実用的ではありません。

この機能をバックポートするために、パッチまたはモンキーパッチを適用できます。私は smtplib.SMTP をサブクラス化し、基になるソケットにモンキーパッチを適用する傾向があります。これは、展開を簡素化し、基本クラスに影響を与える可能性が低く、政治的に正しいバックポートよりも簡単だからです。

Ruby の世界では、モンキーパッチはより容認されていますが、ほとんどの Python サークルでは、この危険ではあるが頻繁に役立つ手法は嫌われています。

私の質問は次のとおりです。そのような決定に直面したことがありますか、またはアドバイスを共有したいと思いますか?

(各アプローチの長所と短所に興味があります)

[アップデート]

pps 実際には、もう少し考えてみると、モンキー パッチは既存のクラスをインプレースで何らかの方法で変更することを意味し、標準の場所からロードするときに新しいコードが呼び出されることを常に想定していました (認めざるを得ませんが、今考えてみると、方法がわかりません)あなたはこれを行うことができます)。それは私がここで提案していることではありません - このサブクラスは、私自身のコードでのみ使用される、私自身のモジュール内の新しいクラスになります。【アンドリュー・クック】

アンドリュー、時間を割いて答えてくれてありがとう。このようにすれば、SMTP.connect コードをいくつかフォークすることになり、元のライブラリが更新されたときにフォークしたコードに変更が反映されないため、眉をひそめられます。私は mokeypatching をより外科的なものと考えていますが、そのような更新は、monkeypatched コードの周りにリファクタリングがある場合、コードを壊す可能性もあります。私のジェダイ マスターをフォークするか、モンキー パッチを適用するかのどちらかが好きではありません。彼らが導くダークサイドに。:-)

[アップデート]

最後に、送信 IP アドレスを選択できる拡張 EHLO 構文を受け入れる SMTP プロキシを作成しました。

s = SMTP('localhost', 8025)
# will use 173.22.213.16 as the outgoing IP address
s.ehlo('example.com 173.22.213.16') 

twistedを使用するとSLOCは 40 未満でした。twistedはネットワーク コードにとって驚くべきものであり、別のプロセスを実行することを犠牲にして、2.7 ですべてを実行できます。

4

1 に答える 1

1

私がすることは、SMTP をサブクラス化し、SMTP.connect()メソッドをほぼ同一のものに置き換えることですが、それself.sock.connect()は source_address (およびそれを設定するための追加の引数) で呼び出されます。

モンキーパッチが何を意味するのか完全にはわかりませんが(ルビーを使用したことはありません)、上記はPythonでは完全に正常だと思います。そのメソッドを上書きできない場合は、先頭にアンダースコアを付けて名前を付けます。私は SMTP を自分で使用したことはありませんが、HTTP ライブラリを使用し、同様のことを行って HTTP サーバーに認証を追加しました。これは有料の専門的な仕事であり、私はそうすることに何の心配もありませんでした (単純な HTTP サーバーは頻繁に使用するためのものではありませんが、場合によっては便利です)。

(代替手段が何であるかがわからないため、長所と短所についての議論を実際に提供することはできません-パッチを掘り出して適用するということですか?それは可能だと思いますが、さらに多くの変更が含まれている可能性があります-パッチが存在することを知っていたら、おそらくそれが私が行っていたことと一致していることを確認するために簡単に読んだでしょうが、それだけです.新しいパッチを適用した「公式」smtplibを作成することは、実際の利益のためにはより多くの作業のように思えます. - これはロケット科学のコードではなく、単なるバインド パラメータです。)

ps私は、古いコードで呼び出された場合でも呼び出しが機能するように、便利なデフォルト値を持つ追加の引数を提供します。

SMTP のソースですが、どのバージョンかはわかりません。ソケットドキュメント; smtplib ドキュメント

pps 実際には、もう少し考えてみると、モンキー パッチは既存のクラスをインプレースで何らかの方法で変更することを意味すると常に想定していました。これにより、標準の場所からロードするときに新しいコードが呼び出されます (認めざるを得ません。今考えてみると、方法がわかりません)。あなたはこれを行うことができます)。それは私がここで提案していることではありません- このサブクラスは、私自身のコードでのみ使用される、私自身のモジュール内の新しいクラスになります。

于 2012-05-25T03:46:14.090 に答える