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

180 投票
10 回答
332241 浏览
提问于 2025-04-16 13:52

我知道Python有个叫“鸭子类型”的概念,但有时候我还是搞不清楚函数的参数类型或者返回值类型。

如果是我自己写的函数,我当然知道这些类型。但是如果别人想用我的函数,他们该怎么知道这些类型呢?我通常会在函数的文档字符串里写类型信息,比如:"...id参数应该是一个整数...""...这个函数会返回一个(字符串, [整数])的元组."

不过,查阅文档字符串里的信息(以及作为程序员把这些信息写进去)真的是应该这么做吗?

编辑:虽然大部分回答都倾向于“是的,要记录文档!”但我觉得对于一些“复杂”的类型,这并不总是那么简单。
比如:怎么简洁地在文档字符串里描述一个函数返回一个元组列表,每个元组的形式是(node_id, node_name, uptime_minutes),而这些元素分别是一个字符串、一个字符串和一个整数呢?
文档字符串的PEP文档没有给出这方面的指导。
我想反对的观点可能是这种情况下应该使用类,但我觉得Python很灵活,因为它允许用列表和元组来传递这些东西,也就是说可以不使用类。

10 个回答

27

其实没有必要,因为Python是一种动态语言,但是如果你想指定一个返回值,可以这样做:

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

不过这对你帮助不大。它不会像静态类型语言(比如Java、C、C++)那样抛出异常。即使你返回了一个字符串,也不会抛出任何异常。

然后对于参数类型,可以这样做:

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

在冒号(:)后面,你可以指定参数类型。这样做也没什么帮助,下面是一个例子来证明这一点:

def printer(a: int) -> int: print(a)

printer("hello")

上面的函数实际上只是返回了None,因为我们没有返回任何东西,但我们确实告诉它我们会返回int,不过就像我说的,这并没有什么用。也许在一些集成开发环境(IDE)中会有帮助(并不是所有的,只有一些,比如pycharm之类的,但在vscode上就没有)。

289

自从2011年以来,情况有了一些变化!现在在Python 3.5中引入了类型提示,你可以用它来标注函数的参数和返回值类型。例如,下面这个:

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

现在可以写成这样:

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

因为你现在可以看到类型,所以有了一种可选的静态类型检查,这会帮助你和你的类型检查工具更好地理解你的代码。

想要了解更多,我建议你去看看PyCharm博客上关于类型提示的文章。

25

动态语言的工作方式就是这样。不过,这并不总是好事,特别是当文档写得很差的时候——有没有人尝试过使用文档不全的Python框架?有时候你不得不去看源代码。

为了避免鸭子类型带来的问题,这里有一些策略:

  • 为你的问题领域创建一种语言
  • 这会帮助你更好地命名事物
  • 使用类型来表示你领域语言中的概念
  • 用领域语言的词汇来命名函数参数

还有一个非常重要的点:

  • 尽量让数据保持本地化!

应该只有少数几个定义明确且文档齐全的类型在传递。其他的东西通过查看代码应该是显而易见的:不要有那些来自远方的奇怪参数类型,让你在查看代码时无法理解...

还有一个相关的内容(也和文档字符串有关),在Python中有一种叫做doctests的技术。用它来记录你的方法应该如何使用,同时还能有很好的单元测试覆盖率!

撰写回答