如何知道函数返回类型和参数类型?

Rab*_*ski 64 python types

虽然我知道Python的鸭子类型概念,但我有时会遇到函数的参数类型或函数返回值的类型.

现在,如果我自己编写函数,我就知道了类型.但是,如果有人想要使用并调用我的函数,他/她应该如何知道这些类型呢?我通常将类型信息放在函数的docstring中(如:"...the id argument should be an integer...""... the function will return a (string, [integer]) tuple.")

但是查找文档字符串中的信息(并将其作为编码器放在那里)真的应该如何完成?

编辑:虽然大多数答案似乎都指向"是的,文档!" 对于"复杂"类型,我觉得这并不总是很容易.
例如:如何在docstring 中简明扼要地描述函数返回元组列表,每个元组的元组(node_id,node_name,uptime_minutes)以及元素分别是字符串,字符串和整数?
文档字符串PEP文档没有给出任何指导.
我想反驳就是在这种情况下应该使用类,但我发现python非常灵活,因为它允许使用列表和元组来传递这些东西,即没有类.

Rsh*_*Rsh 80

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

def greeting(name):
  return 'Hello, {}'.format(name)
Run Code Online (Sandbox Code Playgroud)

现在可以写成:

def greeting(name: str) -> str:
  return 'Hello, {}'.format(name)
Run Code Online (Sandbox Code Playgroud)

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

有关更多解释,我建议您查看PyCharm博客中关于类型提示的博客文章.

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

PYC*_*PYC 27

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

def foo(a) -> int: #after arrow type the return type 
       return 1 + a
Run Code Online (Sandbox Code Playgroud)

但它不会真正帮助你太多。它不会像 java、c、c++ 等静态类型语言那样引发异常。即使您返回一个字符串,也不会引发任何异常。

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

def foo(a) -> int: #after arrow type the return type 
       return 1 + a
Run Code Online (Sandbox Code Playgroud)

在冒号 ( :) 之后您可以指定参数类型。这也无济于事,为了证明这一点,这里有一个例子:

def foo(a: int) -> int:
      return a+ 1
Run Code Online (Sandbox Code Playgroud)

上面的函数实际上只是返回None,因为我们没有返回任何东西,但我们确实告诉它我们会返回int,但正如我所说,这没有帮助。也许它可以在 IDE 中有所帮助(不是全部,但很少有类似pycharm的东西,但不是在 IDE 上vscode


Dar*_*mas 17

这就是动态语言的工作方式.然而,它并不总是一件好事,特别是如果文档很差 - 任何人都试图使用文档记录不佳的python框架?有时您必须恢复阅读源.

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

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

此外,最重要的一点是:

  • 保持数据尽可能本地化!

应该只传递一些明确定义和记录的类型.通过查看代码,其他任何事情都应该是显而易见的:不要通过在代码附近查看来自远处的奇怪参数类型

相关的,(也与docstrings有关),python中有一种技术叫做doctests.使用它来记录您的方法应该如何使用 - 并同时具有良好的单元测试覆盖率!


mur*_*mit 8

我参加了一个 Coursera 课程,有一节课,我们学习了设计秘诀。

在文档字符串格式下,我发现非常有用。

定义区域(底部,高度):
    '''(number, number ) -> number #**TypeContract**
    返回尺寸为 base #**Description** 的区域面积
    和身高

    >>>区域(10,5)#**示例**
    25.0
    >>区域(2.5,3)
    3.75
    '''
    返回(底*高)/2 

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

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


Mac*_*rko 6

是的,您应该使用docstrings使您的类和函数对其他程序员更友好:

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

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


Rab*_*ski 6

十年后回答我自己的问题,现在我用两件事来解决这个问题:

  • 类型提示(如其他答案中已经提到的)
  • 数据类,当参数或返回类型提示变得笨拙/难以阅读时

作为后者的一个例子,假设我有一个函数

def do_something(param:int) -> list[tuple[list, int|None]]:
   ...
   return result
Run Code Online (Sandbox Code Playgroud)

我现在将使用数据类重写,例如:

from dataclasses import dataclass

@dataclass
class Stat:
    entries: list
    value: int | None = None

 def do_something(param:int) -> list[Stat]:
   ...
   return result
Run Code Online (Sandbox Code Playgroud)