【问题标题】:How to know function return type and argument types?如何知道函数返回类型和参数类型?
【发布时间】:2011-07-17 05:14:00
【问题描述】:

虽然我知道 Python 的鸭子类型概念,但有时我会为函数的参数类型或函数返回值的类型而苦恼。

现在,如果我自己编写函数,我确实知道类型。但是如果有人想使用和调用我的函数,他/她怎么知道类型呢? 我通常将类型信息放在函数的文档字符串中(例如:"...the id argument should be an integer...""... the function will return a (string, [integer]) tuple."

但是在文档字符串中查找信息(并作为编码人员将其放在那里)真的是它应该完成的方式吗?

编辑:虽然大多数答案似乎都指向“是的,文档!”我觉得这对于“复杂”类型并不总是那么容易。
例如:如何在一个函数返回一个元组列表的文档字符串中简洁描述,每个元组的形式为 ( node_id, node_name, uptime_minutes) 并且元素分别是字符串、字符串和整数?
docstring PEP 文档没有对此提供任何指导。
我猜反驳是在这种情况下应该使用类,但我发现 python 非常灵活,因为它允许使用列表和元组传递这些东西,即 没有 类。

【问题讨论】:

  • 简短的回答是“是”。长答案是“是的,当然”。我不知道你是否看过很多 Python 代码,但你可能应该更新这个问题以指出你实际使用的包,这样我们就可以指导你阅读你可以阅读的代码以了解情况如何在您现在实际使用的库代码中完成。
  • @S.Lott:我目前正在为 mechanize 软件包苦苦挣扎,但我想它只是(不幸地)记录不充分。
  • Python 很酷,因为您可以快速编写大量代码,而且您不必担心诸如返回类型、参数类型、运行时性能、必须使用和维护您的意大利面条代码的人等日常事务未来 10 年等等。叹息。

标签: python types


【解决方案1】:

自 2011 年以来,情况发生了一些变化!现在 Python 3.5 中有 type hints ,您可以使用它来注释参数并返回函数的类型。例如:

def greeting(name):
  return 'Hello, {}'.format(name)

现在可以这样写:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)

您现在可以看到类型,有一些可选的静态类型检查将帮助您和您的类型检查器调查您的代码。

如需更多解释,我建议查看PyCharm blog 中关于类型提示的博文。

【讨论】:

  • 请注意,在同一 PEP-0484 中还建议为 Python 2.7 here 使用类型提示语法。它在 PyCharm 中工作,至少从 v 2017.3 开始。
  • 如果定义完全相同的 greeting 函数返回一个 int 类型的对象,则不会引发错误。那么如果你明确提到返回类型,但不遵守规则并返回不同类型的对象,那么这种类型检查有什么用呢?
  • @Arashsyh:是的,你是对的,类型提示不会将 Python 变成静态类型的语言,这取决于你以正确的方式使用正确的类型。这些类型提示可以帮助您 - 更快地开发,自我记录您的代码或在您搞砸时收到警告。特别是当您使用 PyCharm(或类似的 IDE)时,它会在您使用不同类型时发出警告,并帮助您处理其他一些事情。我建议阅读上面答案中建议的博客文章。
  • 计算速度更快吗?
  • 直到今天,我对 Python3 中的数据类型没有任何问题。但是最近我错过了 Pandas 中的一个返回类型,有些头疼——当然是因为我自己的错误,而不是因为 Python3。我没有注意到 Python3 的这种巨大变化(来自 Java,我曾经想要它)。目前我找到了你的答案——现在我正在重写东西,因为这太棒了。从 2011 年开始?可怕!网上有很多代码没有考虑类型提示的可能性,这向其他人清楚地表明了程序员的意图以及在自己被蒙住眼睛的时候提供帮助。谢谢!
【解决方案2】:

这就是动态语言的工作方式。但这并不总是一件好事,尤其是在文档很差的情况下-有人试图使用文档记录不佳的python框架吗?有时您必须重新阅读源代码。

以下是一些避免鸭子打字问题的策略:

  • 为您的问题领域创建一种语言
  • 这将帮助您正确命名内容
  • 使用类型来表示您的领域语言中的概念
  • 使用领域语言词汇表命名函数参数

另外,最重要的一点:

  • 尽可能将数据保存在本地!

应该只传递一些定义明确且记录在案的类型。通过查看代码,其他任何事情都应该是显而易见的:不要有奇怪的参数类型来自遥远的地方,而您在代码附近无法弄清楚......

相关,(也与文档字符串相关),python 中有一种称为doctests 的技术。使用它来记录您的方法的预期使用方式 - 同时具有良好的单元测试覆盖率!

【讨论】:

  • Numpy 文档是上述答案中所述哲学的一个很好的代表性示例。
【解决方案3】:

我参加了一个 coursera 课程,其中有一堂课,我们学习了设计秘诀。

下面的文档字符串格式我发现 preety 很有用。

def 面积(底,高): '''(number, number) -> number #**TypeContract** 返回具有尺寸基数的三角形区域#**描述** 和身高 >>>面积(10,5)#**示例** 25.0 >>面积(2.5,3) 3.75 ''' 返回(底*高)/2

我认为如果以这种方式编写文档字符串,它可能对开发人员有很大帮助。

视频链接[观看视频]https://www.youtube.com/watch?v=QAPg6Vb_LgI

【讨论】:

    【解决方案4】:

    其实没有必要,因为python是一种动态语言,BUT如果你想指定一个返回值那就这样做

    def foo(a) -> int: #after arrow type the return type 
           return 1 + a
    

    在上面的例子中,如果你给它一个字符串周界,比如"hello",它会返回int,然后它会抛出这个异常TypeError: unsupported operand type(s) for +: 'int' and 'str',因为它要求一个int值,我们给它一个字符串值和最后因为我们不能添加 int 和 string

    然后对于参数类型执行此操作

    def foo(a: int) -> int:
          return a+ 1
    

    冒号后(:)可以指定参数类型

    【讨论】:

      【解决方案5】:

      是的,你应该使用文档字符串来让你的类和函数对其他程序员更友好:

      更多:http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring

      有些编辑器允许您在键入时查看文档字符串,因此确实让工作更轻松。

      【讨论】:

      • +1:记录它,这是唯一理智的方法,静态类型语言也是如此。返回类型只是整个画面的一小部分。
      • 我喜欢我的类型,非常感谢。文档 + 类型 = 天堂
      【解决方案6】:

      是的。

      在 Python 中,函数并不总是必须返回相同类型的变量(尽管如果您的函数总是返回相同类型,您的代码将更具可读性)。这意味着您不能为函数指定单一的返回类型。

      同样,参数也不必总是相同的类型。

      【讨论】:

        【解决方案7】:

        例如:如何在文档字符串中简洁地描述一个函数返回一个元组列表,每个元组的形式为(node_id,node_name,uptime_minutes),元素分别为字符串、字符串和整数?

        嗯...没有“简洁”的描述。这很复杂。你设计的很复杂。它需要文档字符串中的复杂文档。

        抱歉,复杂性是——好吧——复杂。

        【讨论】:

        • 好的。题外话(有点):但是什么是更清洁的设计呢?上课?
        • @Rabarberski:不一定。复杂性在这里听起来是不可避免的。简洁并不总是可以实现甚至是可取的。
        • 记录这类事情的一个明显方法是使用类似于 Java 泛型的东西,例如:list>。但这不是 Python 的方式,无论好坏。
        【解决方案8】:

        是的,因为它是一种动态类型语言;)

        阅读此内容以供参考:PEP 257

        【讨论】:

          【解决方案9】:

          文档字符串(和一般文档)。 Python 3 引入了(可选的)函数注释,如 PEP 3107 中所述(但不要遗漏文档字符串)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-01-03
            • 1970-01-01
            • 2018-12-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多