3

我对 python3.3 中引入的一个新的 smtplib 功能感兴趣:能够绑定到多宿主机器(或具有多个 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时它的SLOC低于 40 ,twisted 对于网络代码来说非常棒,而且我可以在 2.7 中做任何事情,但要以运行另一个进程为代价。

4

1 回答 1

1

我要做的是子类 SMTP 并SMTP.connect()用一个几乎相同的方法替换该方法,但它self.sock.connect()使用 source_address 调用(以及一个额外的参数来设置它)。

我不完全确定猴子修补是什么意思(我从未使用过 ruby​​),但我认为以上对于 python 来说是完全正常的。如果您不打算覆盖该方法,那么它将使用前导下划线命名。我自己没有使用过 SMTP,但我使用了 HTTP 库并做了类似的事情来向 HTTP 服务器添加身份验证。这是有偿的,专业的工作,我对此完全不担心(简单的 HTTP 服务器不适合大量使用,但在某些情况下它很有用)。

(我真的不能提供任何关于利弊的讨论,因为我看不出有什么替代方案——你的意思是挖出补丁并应用它吗?我想你可以这样做,但它可能包含更多的变化——如果我知道存在补丁,我可能会快速阅读它以确保它与我正在做的事情一致,但仅此而已。创建一个新的、打补丁的“官方”smtplib 似乎需要做更多的工作却没有真正的收获- 这不是火箭科学代码,它只是一个绑定参数。)

ps 我会为任何额外的参数提供一个有用的默认值,这样如果用旧代码调用,调用仍然可以工作。

SMTP 的来源,虽然我不确定是什么版本套接字文档smtplib 文档

pps 实际上,再想一想,我一直认为猴子修补意味着以某种方式就地修改现有类,以便在从标准位置加载时调用新代码(我必须承认,现在我想到了,我不知道如何你可以这样做)。这不是我在这里建议的 - 这个子类将是一个新类,在我自己的模块中,仅由我自己的代码使用。

于 2012-05-25T03:46:14.090 回答