【问题标题】:How do I specify input and output data types in python comments?如何在 python 注释中指定输入和输出数据类型?
【发布时间】:2018-12-22 05:13:18
【问题描述】:

我已经看到了一些编写 cmets 的标准,这些标准与 Python 中函数期望和返回的数据类型有关。是否就哪一个是最佳实践达成共识?

http://www.python.org/dev/peps/pep-3107/ 中的新功能是我应该开始使用的吗?

【问题讨论】:

    标签: python documentation comments types


    【解决方案1】:

    函数注解没有特定用途,它们可以用于任何事情。

    可以编写工具来从注释中提取信息并执行任何您想做的事情,包括检查类型或生成文档。但是 python 本身并没有对这些信息做任何事情。您可以使用完全不同的目的,即提供将在参数上调用的函数或声明可能返回值的字符串。

    注解可以是任何对象:

    def somefunc(param1: "string annotation", 
                 param2: 151631,  
                 param3: any_object): -> "some information here":
    

    您可以使用以下方法检索对象:

    print (somefunc.func_annotations)
    {'param1': "string annotation", 
     'param2': 151631,  
     'param3': <object any_object>,
     'return': "some information here"}
    

    PEP 提供的用例建议:

    • 提供打字信息
      • 类型检查
      • 让 IDE 显示函数期望和返回的类型
      • 函数重载/泛型函数
      • 外语桥梁
      • 适应
      • 谓词逻辑函数
      • 数据库查询映射
      • RPC 参数封送处理
    • 其他信息
      • 参数和返回值的文档

    由于函数注解语法太新,所以真的不适合任何生产工具使用。

    我建议使用其他方法来记录它。我使用 epydoc 生成我的文档,它可以从 docstrings 中读取参数类型信息:

    def x_intercept(m, b):
        """
        Return the x intercept of the line M{y=m*x+b}.  The X{x intercept}
        of a line is the point at which it crosses the x axis (M{y=0}).
    
        This function can be used in conjuction with L{z_transform} to
        find an arbitrary function's zeros.
    
        @type  m: number
        @param m: The slope of the line.
        @type  b: number
        @param b: The y intercept of the line.  The X{y intercept} of a
                  line is the point at which it crosses the y axis (M{x=0}).
        @rtype:   number
        @return:  the x intercept of the line M{y=m*x+b}.
        """
        return -b/m
    

    这个例子来自epydoc's website。它可以生成各种格式的文档,并且可以从您的类和调用配置文件中生成良好的图表。

    【讨论】:

    【解决方案2】:

    如果您使用epydoc 生成 API 文档,您有三种选择。

    • Epytext.

    • 重构文本,RST。

    • JavaDoc 表示法,有点像 epytext。

    我推荐 RST,因为它可以很好地与 sphinx 一起生成包含 API 参考的整体文档套件。 RST 标记定义为here。您可以指定的各种 epydoc 字段定义为 here

    示例。

    def someFunction( arg1, arg2 ):
        """Returns the average of *two* (and only two) arguments.
    
        :param arg1: a numeric value
        :type arg1: **any** numeric type
    
        :param arg2: another numeric value
        :type arg2: **any** numeric type
    
        :return: mid-point (or arithmetic mean) between two values 
        :rtype: numeric type compatible with the args.
        """
        return (arg1+arg2)/2
    

    【讨论】:

      【解决方案3】:

      Python 3.5 官方typing

      https://docs.python.org/3/library/typing.html

      此更新使类型成为语言的实际部分。

      例子:

      #!/usr/bin/env python3
      
      from typing import List
      
      def f(x: int, ys: List[float]) -> str:
          return "abc"
      
      # Good.
      f(1, [2.0, 3.0])
      
      # Bad.
      f("abc", {}) # line 12
      
      x = 1
      x = "a" # line 15
      
      y = [] # type: List[int]
      y.append("a") # line 18
      

      这段代码运行正常:Python 3.5 默认不强制输入。

      但是静态 linter 可以使用它来诊断问题,例如:

      sudo pip3 install mypy
      mypy a.py
      

      给予:

      a.py:12: error: Argument 1 to "f" has incompatible type "str"; expected "int"
      a.py:12: error: Argument 2 to "f" has incompatible type Dict[<nothing>, <nothing>]; expected List[float]
      a.py:15: error: Incompatible types in assignment (expression has type "str", variable has type "int")
      a.py:18: error: Argument 1 to "append" of "list" has incompatible type "str"; expected "int"
      

      像 Pycharm 这样的现有静态分析器已经可以解析 Sphinx 文档类型,但这次语言更新提供了一种可能会流行的官方规范方式。

      Sphinx 1.8.2 似乎还不支持它,但这只是时间问题:Python 3: Sphinx doesn't show type hints correctly

      【讨论】:

        猜你喜欢
        • 2021-07-18
        • 2018-11-21
        • 2011-07-04
        • 1970-01-01
        • 2023-02-02
        • 1970-01-01
        • 2016-11-08
        • 1970-01-01
        • 2021-07-14
        相关资源
        最近更新 更多