【问题标题】:Should I prefer 'asking for permission' in this case?在这种情况下,我应该更喜欢“请求许可”吗?
【发布时间】:2015-12-25 18:14:45
【问题描述】:

在我的函数中,我期待一个可能是tuplestr 的参数。作为 Python 新手,我了解到“请求宽恕”比“请求许可”要好。因此,我不检查参数的类型,而是这样做:

def f(a):
    try:  # to handle as tuple
        e1, e2, e3 = a
        ...
    except ValueError:  # unpacking failed, so must be a string.
        pass
    # handle as string

但是,这并不总是有效。如果a 是长度为3str 怎么办?代码会将其视为元组。

在这种情况下我该怎么办?求助于类型检查?它不那么“Pythonic”吗?请解释最“Pythonic”的解决方案以及为什么会这样。

【问题讨论】:

  • 参数是用户输入的吗?可能有比在函数内部更好的检查格式的地方。
  • 重要的是,您使用具有两种不同参数类型的同一个函数吗?
  • 我建议使用isinstance() 而不是type() stackoverflow.com/questions/1549801/…
  • 使用关键字参数并接受两个不同的参数?
  • 你会拆分字符串最终得到一个元组吗?

标签: python exception coding-style


【解决方案1】:

Python 有 isinstance() 函数是有原因的。有时检查参数的类型是正确的做法;在这里完全可以接受。

【讨论】:

    【解决方案2】:

    在 Python 中进行类型检查是非常好的,尤其是当您想要这样做以实现函数重载时。

    但我建议您对字符串而不是元组进行类型检查。虽然看起来你总是会传递一个元组,但在很多情况下传递不同的序列也可能很有意义,例如列表也很好。

    所以你应该让逻辑保持原样,但首先检查字符串输入:

    def f(a):
        if isinstance(a, str): # in Python 2, check against `basestring`
            # handle as string
            # …
        else:
            # handle as tuple
            e1, e2, e3 = a
            # …
    

    这样,当解包没有正确成功时,你会得到一个适当的异常,例如,如果有人传递了一个 2 元素元组。在您的原始代码中,您必须以某种方式自己处理这个问题(以避免运行认为它是字符串的代码)。

    【讨论】:

      【解决方案3】:

      显式优于隐式:定义两个函数,一个用于元组,另一个用于字符串。第二个最佳选择是,拥有一个带有三个参数的函数,其中两个是可选的:

      def f(e1, e2=None, e3=None):
          if e2 is None and e3 is None:
              # a string
          else:
              # three strings
      

      最好的可能性是检查参数的类型:

      def f(a):
          if isinstance(a, basestring):
              # a string
          else:
              # perhaps a tuple
      

      【讨论】:

        猜你喜欢
        • 2013-12-01
        • 2011-01-17
        • 2022-07-22
        • 2013-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        相关资源
        最近更新 更多