小编got*_*uru的帖子

如何编写python中对象属性(属性)存在的接口(合约)?

我想对某个函数的参数签定合同,以强制参数对象必须具有特定的属性。我了解python不是严格类型的语言,但是有时具有合同和接口非常有用。Python现在具有类型提示,这很好,因此我们可以这样做:

def myfunc(myparam: MyType) -> SomeType:
    myparam.myprop # this should exist
Run Code Online (Sandbox Code Playgroud)

但是,如何说MyType必须具有特定的对象属性(myprop),而又不能在运行时插入断言和引发异常?我可以用abc元类定义抽象类,该类可以用作接口。

from abc import ABC, abstractmethod
class MyInterface(ABC):
     @property
     @abstractmethod
     def myprop(self) -> int: pass
Run Code Online (Sandbox Code Playgroud)

现在在代码中的某个地方,我可以将MyType定义为:

class MyType(MyInterface):
    myprop = 8
Run Code Online (Sandbox Code Playgroud)

它正在工作,但是 myprop是类属性,而不是对象属性(属性)。我当然可以这样做:

class MyType(MyInterface):
    myprop = 0
    def __init__(self):
        self.myprop = 8
Run Code Online (Sandbox Code Playgroud)

很好,但是我必须定义一个(不必要的)类(“静态”)属性,并使用对象属性有效地将其隐藏。不太干净。而且现在我有一个myprop的默认值,这不是我想要的。但是,如果我这样做:

class MyType(MyInterface):
    myprop = None  # wrong type here
    def __init__(self):
        self.myprop = 8
Run Code Online (Sandbox Code Playgroud)

这是错误的,因为myprop 必须为 int且不能为None,这是由linter 正确捕获的。应该有一个没有类属性的对象属性。

目标是像mypy这样的静态检查器可以捕获实现错误,其中类不遵循已定义的接口或协定,而该协定或协定要求参数实例必须具有某些属性。

什么是pythonic(或不是pythonic)的实现方式?

python abstract-class interface contract python-3.x

5
推荐指数
1
解决办法
56
查看次数

如何在Haskell中触发类型错误?

我们假设我有一个类型

data F a = A a | B
Run Code Online (Sandbox Code Playgroud)

我实现这样的功能f :: F a -> F a -> F a:

f (A x) B = A x
f B (A _) = B
f (A _) (A x) = A x
Run Code Online (Sandbox Code Playgroud)

但是没有这样的事情在f B B逻辑上是不可能的,所以我想要:

f B B = GENERATE_HASKELL_COMPILE_ERROR
Run Code Online (Sandbox Code Playgroud)

这当然不起作用.省略定义或使用f B B = undefined不是解决方案,因为它会生成运行时异常.我想得到编译时类型错误.

编译器拥有所有信息,它应该能够推断出我犯了一个逻辑错误.如果说我声明let z = f (f B (A 1)) B应该是一个立即编译时错误,而不是一些运行时异常可以隐藏在我的代码中多年.

我找到了一些关于合同的信息,但我不知道如何在这里使用它们,我很好奇是否有任何标准方法在Haskell中执行此操作.


编辑:事实证明,我试图做的是被称为依赖类型,但在Haskell中还没有完全支持.然而,使用索引类型和几个扩展可能会生成类型错误.David Young的解决方案似乎更简单,而Jon Purdy创造性地使用类型操作符.我接受第一个,但我喜欢两个.

haskell types compile-time

4
推荐指数
1
解决办法
393
查看次数