Python 具有自己类型的PEP-484类型注释

Python 具有自己类型的PEP-484类型注释,python,numpy,types,cython,type-hinting,Python,Numpy,Types,Cython,Type Hinting,PEP-484为类型注释提供语义。 这些都非常适合于a)文档和b)IDE帮助。他们不太倾向于代码优化 例如,不幸的是,在Cython中也不可能使用PEP 484注释 或者使用Numba,后者使用自己的注释格式,如字符串“float64(int32,int32)” 我如何在PEP 484框架内使用我自己的类型? 我明确地不想破坏PEP-484语义,而是用附加信息扩充现有类型 对我自己的类型检查器可见,但对任何符合PEP-484的类型检查器或IDE不可见 以下内容是否在PEP-484语义中解释为

PEP-484为类型注释提供语义。 这些都非常适合于a)文档和b)IDE帮助。他们不太倾向于代码优化

例如,不幸的是,在Cython中也不可能使用PEP 484注释

或者使用Numba,后者使用自己的注释格式,如字符串“float64(int32,int32)”

我如何在PEP 484框架内使用我自己的类型? 我明确地不想破坏PEP-484语义,而是用附加信息扩充现有类型 对我自己的类型检查器可见,但对任何符合PEP-484的类型检查器或IDE不可见

以下内容是否在PEP-484语义中解释为列表[int]

class Int32(int): pass
x = [1]   # type: List[Int32]
像这样更别致的款式怎么样?

def combine(typeA, typeB):
    class X(typeA, typeB): pass
    return X

class Metre(): pass

# is y an 'int' to PEP-484 typecheckers?
y = 1 # type: combine(Int32, Metre)

对于库使用类型暗示(无论是类型解析还是类型检查)有什么建议吗?

自从Python 3.5以来,我们不仅有,而且还实现了它

为了完全理解,您可能需要通读这3个文档。但对于您的具体情况,简短的回答是,在PEP484领域中,您可以通过4种方式处理自己的类型:

  • 只需使用自己的类型进行注释
  • 创造,
  • 使用,或
  • 使用

  • 如果你的追求高于一切:

    其他信息对我自己的类型检查器可见,但对任何符合PEP-484的类型检查器不可见

    第二种方法就是这样。如果您这样做:

    Int32 = int
    Int64 = int
    
    x = 0 # type: Int32
    y = 0 # type: Int64
    
    然后,PEP484领域中的
    Int32
    Int64
    将是相同的,但是您可以通过使用community Maintened查看代码的AST(抽象语法树)来添加一些额外的检查。该模块除了解析代码外还解析类型注释,因此您可以读取所使用的确切注释,从而获得
    x
    y
    的一些附加类型信息


    如果隐身不是首要任务,那么:

    • 而不是
      类Int32(int):pass
      我宁愿
      键入.NewType('Int32',int)
      ,和

    • 我将使用
      键入.Union[Int32,meter]
      而不是
      combine(Int32,meter)

    i、 e

    在上面的代码中,您可以运行community Maintened



    现在(2016年)和都在积极发展。并不是所有的东西都像预期的那样工作,但据我所知,它们已经足够适合许多用例,而且似乎没有其他选择。

    关于
    numpy
    和484的类似问题-我对研究不同类型的系统感兴趣。我希望有一个具有Shen()灵活性的系统,并且能够定义自己的类型和类型规则。第一步是为测量单位构建静态检查器。484类型语义非常诱人,b/c它们非常灵活,例如,我(希望)表示变量的类型为Int32,同时具有维度米。优化器对int32很满意,检查了物理单位,gui将y识别为int。numpy问题的链接很好,这是正确的长期方向,我也喜欢datashape项目。首先,我对类型方面更感兴趣的是如何在484上下文中处理自己的类型,以及如何解析程序中的类型信息。当然,我希望将来外部库能够最大限度地共享类型注释。
    Int32 = typing.NewType('Int32', int)
    
    class Metre:
        pass
    
    x = [Int32(1)]  # type: List[Int32]
    y = Int32(1) # type: typing.Union[Int32, Metre]
    
    print(x[0] + 1) # ok, since Int32 is still int
    y = Metre() # ok, since y can be Int32 or Metre