【问题标题】:Call with keyword argument only on Python 3.3 or higher仅在 Python 3.3 或更高版本上使用关键字参数调用
【发布时间】:2015-04-04 02:18:46
【问题描述】:

我正在尝试使用logging's SMTPHandler。从 Python 3.3 开始,您可以指定 timeout 关键字参数。如果您在旧版本中添加该参数,它将失败。为了解决这个问题,我使用了以下方法:

import sys

if sys.version_info >= (3, 3):
    smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT, timeout=20.0)
else:
    smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT)

有更好的方法吗?

【问题讨论】:

标签: python


【解决方案1】:

这是另一种略有不同的方法:

from logging.handlers import SMTPHandler
import sys

if sys.version_info >= (3, 3):
    # patch in timeout where available
    from functools import partial
    SMTPHandler = partial(SMTPHandler, timeout=20.0)

现在您可以在其余代码中使用:

smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT)

并且知道timeout 参数正在被使用(如果可用)。这仍然依赖于静态版本检查,但这意味着所有特定于版本的配置都在一个地方,并且可能会减少其他地方的重复。

【讨论】:

    【解决方案2】:

    使用异常处理而不是测试版本:

    try:
        smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT, timeout=20.0)
    except TypeError:
        # Python < 3.3, no timeout parameter
        smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT)
    

    现在您可以想象通过补丁或反向移植模块就地升级您的标准库,它会继续工作。

    【讨论】:

      【解决方案3】:

      我会这样做:

      kargs = {}
      if sys.version_info >= (3, 3):
          kargs['timeout'] = 20.0
      
      smtp_handler = SMTPHandler(SMTP_SERVER, FROM_EMAIL, TO_EMAIL, SUBJECT, **kargs)
      

      更新try/catch 的其他答案的想法很好,但它假设它由于 timeout 参数而失败。在这里,我提出了一个关于论证可用性的超智能测试。如果这个类的未来版本添加越来越多的可选参数怎么办? (免责声明:未声称可移植):

      if 'timeout' in SMTPHandler.__init__.__code__.co_varnames:
          kargs['timeout'] = 20.0
      

      【讨论】:

      • kargs = {'timeout': 20.0} if sys.version_info &gt;= (3, 3) else {} 三元形式
      猜你喜欢
      • 1970-01-01
      • 2014-11-21
      • 2020-03-07
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多