如何获知函数的返回类型和参数类型?
我知道Python有个叫“鸭子类型”的概念,但有时候我还是搞不清楚函数的参数类型或者返回值类型。
如果是我自己写的函数,我当然知道这些类型。但是如果别人想用我的函数,他们该怎么知道这些类型呢?我通常会在函数的文档字符串里写类型信息,比如:"...id参数应该是一个整数..."
和"...这个函数会返回一个(字符串, [整数])的元组."
不过,查阅文档字符串里的信息(以及作为程序员把这些信息写进去)真的是应该这么做吗?
编辑:虽然大部分回答都倾向于“是的,要记录文档!”但我觉得对于一些“复杂”的类型,这并不总是那么简单。
比如:怎么简洁地在文档字符串里描述一个函数返回一个元组列表,每个元组的形式是(node_id, node_name, uptime_minutes),而这些元素分别是一个字符串、一个字符串和一个整数呢?
文档字符串的PEP文档没有给出这方面的指导。
我想反对的观点可能是这种情况下应该使用类,但我觉得Python很灵活,因为它允许用列表和元组来传递这些东西,也就是说可以不使用类。
10 个回答
其实没有必要,因为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
上就没有)。
动态语言的工作方式就是这样。不过,这并不总是好事,特别是当文档写得很差的时候——有没有人尝试过使用文档不全的Python框架?有时候你不得不去看源代码。
为了避免鸭子类型带来的问题,这里有一些策略:
- 为你的问题领域创建一种语言
- 这会帮助你更好地命名事物
- 使用类型来表示你领域语言中的概念
- 用领域语言的词汇来命名函数参数
还有一个非常重要的点:
- 尽量让数据保持本地化!
应该只有少数几个定义明确且文档齐全的类型在传递。其他的东西通过查看代码应该是显而易见的:不要有那些来自远方的奇怪参数类型,让你在查看代码时无法理解...
还有一个相关的内容(也和文档字符串有关),在Python中有一种叫做doctests
的技术。用它来记录你的方法应该如何使用,同时还能有很好的单元测试覆盖率!