【发布时间】:2012-05-24 23:39:53
【问题描述】:
我对 python3.3 中引入的新 smtplib 功能感兴趣:能够绑定到 multihomed 机器(或具有多个 IP 地址的机器)中的特定 IP 地址。
我想使用的许多构建块都没有移植到 3.3 或端口非常不稳定,所以仅仅因为这个特性而使用 3.3 的想法是不切实际的。
为了向后移植此功能,我可以使用补丁或猴子补丁。我倾向于子类化 smtplib.SMTP 并对底层套接字进行猴子补丁,因为它简化了部署,似乎不太可能影响基类并且比政治上正确的反向移植更容易。
在 ruby 世界中,monkeypatching 更容易被容忍,但在大多数 python 圈子中,这种危险但经常有用的技术是不受欢迎的。
我的问题是:您有没有遇到过这样的决定和/或想分享一些建议?
(我对每种方法的优缺点都很感兴趣)
[更新]
pps 实际上,再想一想,我一直认为猴子修补意味着以某种方式就地修改现有类,以便在从标准位置加载时调用新代码(我必须承认,现在我想到了,我有不知道你怎么能做到这一点)。这不是我在这里建议的 - 这个子类将是一个新类,在我自己的模块中,仅由我自己的代码使用。 [安德鲁库克]
安德鲁,感谢您花时间回答。这样我会分叉一些 SMTP.connect 代码,它也令人不悦,因为当原始库更新时,我的分叉代码不会包含更改。我认为 mokeypatching 更具有外科手术性,但如果对 monkeypatched 代码进行任何重构,此类更新也有可能破坏代码。要么分叉要么给我的绝地大师们打补丁,否则他们会引导他们走向黑暗的一面。 :-)
[更新]
最后我只写了一个 SMTP 代理,它接受扩展的 EHLO 语法,允许选择传出 IP 地址:
s = SMTP('localhost', 8025)
# will use 173.22.213.16 as the outgoing IP address
s.ehlo('example.com 173.22.213.16')
使用 twisted 低于 40 SLOC,twisted 对于网络代码来说是惊人的,我可以在 2.7 中做任何事情,但需要运行另一个进程。
【问题讨论】:
-
对不起;我知道这不是一个真正的答案,但这不是 SMTP 的 local_hostname 参数所做的(而且它一直是“永远”的选项)?
-
@andrewcooke:我不这么认为,AFAIK local_hostname 仅用于 helo 和 ehlo 之类的命令(否则名称由 socket.getfqdn 猜测)-但套接字的实际 IP 地址将绑定将由底层操作系统决定。
-
你说得对,现在我阅读了源代码。
标签: python monkeypatching backport