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


84

虽然我知道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非常灵活,因为它允许使用列表和元组(即没有类)传递这些东西。


2
简短的回答是“是”。长答案是“当然可以”。我不知道您是否看过很多Python代码,但您可能应该更新问题以指出实际使用的软件包,以便我们将您定向到您可以阅读的代码,以查看库代码中的工作方式现在正在实际使用。
S.Lott

@ S.Lott:我目前正在努力使用机械化程序包,但我想它只是(不幸地)记录不好。
Rabarberski

4
Python很酷,因为您可以快速编写大量代码,而不必担心世俗的事情,例如返回类型,参数类型,运行时性能,在接下来的十年中必须使用和维护您的意大利面条式代码的人等。 。
jarmod 2013年

Answers:


120

自2011年以来情况发生了一些变化!现在,Python 3.5中提供类型提示,可用于注释参数并返回函数的类型。例如:

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

现在可以这样写:

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

正如您现在看到的类型一样,存在一些可选的静态类型检查,这将帮助您和您的类型检查器研究代码。

有关更多解释,我建议看一下PyCharm博客中有关类型提示的博客文章


请注意,此处在同一PEP-0484中也为Python 2.7建议了类型提示语法 。至少从2017.3版开始,它可以在PyCharm中使用。
viddik13

1
如果定义完全相同的greeting函数返回一个int类型的对象,则不会引发任何错误。那么,如果您明确提及返回类型,但不遵守规则并返回不同类型的对象,这种类型检查的用途是什么?
Arashsyh

2
@Arashsyh:是的,您是对的,类型提示不会将Python变成静态类型的语言,取决于您以正确的方式使用正确的类型。这些类型提示可以帮助您-更快地开发,自记录代码或在出现问题时得到警告。尤其是当您使用PyCharm(或类似的IDE)时,它会在您使用其他类型时发出警告,并可以帮助您解决其他问题。我建议阅读上面答案中建议的博客文章。
Nerxis

计算速度更快吗?
布莱斯·韦恩

17

这就是动态语言的工作方式。不过,这并不总是一件好事,尤其是在文档不多的情况下-是否有人尝试使用文档不充分的python框架?有时您必须恢复阅读源代码。

以下是一些避免鸭类输入出现问题的策略:

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

另外,最重要的一点之一是:

  • 保持数据尽可能本地!

应该只传递一些定义明确并记录在案的类型。通过查看代码,其他任何事情都应该显而易见:不要从遥远的地方找到怪异的参数类型,而不能通过查看代码附近来弄清楚...

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


1
Numpy文档是上述答案中所阐明的哲学的一个很好的代表示例。
杰里(Jerry)

5

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

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

一些编辑器允许您在键入时查看文档字符串,因此确实使工作变得更容易。


+1:记录下来,这是唯一的明智方法,对于静态类型的语言也是如此。返回类型在整个图中微不足道。
2011年

我很喜欢我的类型,非常感谢您。文档+类型=天堂
masm64 '19

5

我参加了一个课程课程,其中有一堂课,我们被教导有关设计配方的知识。

在docstring格式以下,我发现petety有用。

def面积(基准,高度):
    '''(数字,数字)->数字#** TypeContract **
    返回维数为#**描述**的区域
    和高度

    >>>区域(10,5)#**示例**
    25.0
    >>面积(2.5,3)
    3.75
    '''
    返回(基数*高度)/ 2 

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

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


2

是的。

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

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


1

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

嗯...对此没有“简洁”的描述。这很复杂。您已将其设计为复杂的。并且它需要在文档字符串中包含复杂的文档。

对不起,但是复杂性很复杂。


2
好。题外(排序):那么什么是更干净的设计?上课吗
Rabarberski

@Rabarberski:不一定。在这里,复杂性听起来是不可避免的。简洁并非总是可以实现的,甚至不是理想的。
S.Lott

记录这种事情的一种明显方法是使用类似于Java泛型的东西,例如:list <tuple <int,str,int >>。但这不是Python的方法,无论好坏。
skyler 2012年


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.