c# - Python 中的参数可以是逆变的还是协变的?

标签 c# python static-typing dynamic-typing

我刚刚研究了静态语言(更具体地说是 C#)中的协变和逆变。这个概念对我来说相当清楚,但我对如何将其应用于像 Python 这样的动态语言持怀疑态度。

由于Python是鸭子类型(或结构类型),在我看来,这种语言甚至没有方差和协方差的概念?

如果我没记错的话,像逆变和协变之类的事情会在 C# 等语言的编译时进行检查,这是可能的,因为变量具有类型,并且它绑定(bind)到的值也具有类型,并且这些必须匹配或者是共(ntra)-或不变的。然而,由于像 Python 这样的语言没有在编译时键入的概念,所以我不知道如何应用这个概念。

有什么想法吗?

我的想法: 协方差的概念意味着每当我们期望 X 的类型时,X 的任何子类也会如此。所以,在 Python 中这不会出现,因为没有类型检查来执行此操作。唯一进行的检查是对象是否通过方法和属性实现了必要的实现。

例如,在 C# 中,我们有一个方法:

void DoStuff(Person p)
{
    p.Dance();
};

我们可以很好地使用 Student 的实例调用此方法(如果这是 Person 的子类)。

现在,在Python中,我们可以很好地传入一个在继承层次结构中与Person没有任何关系的Bird对象(除非它也继承自object),只要这个鸟实现了舞蹈().

这就是我询问这个​​概念的原因。据我了解,Python 在……一切事物中都是协变和逆变的?

最佳答案

实际上,这并不完全是(我的理解)方差。方差与类型构造函数的行为有关,例如 C# 中的泛型。使用Student代替Person是普通的子类型。使用List<Student>代替Lis<Person>是主语或协变和逆变。

至于实际问题:Python 没有静态类型系统,因此没有类型构造函数之类的概念。语言根本不关心这些事情。它只是继续并允许您传递任何值,如果它有效,那就太好了。

但是,方差的概念在任何具有子类型和非原子值效果的语言中都非常有用。例如,虽然没有List<Person> ,您可能(无需告诉语言,因为语言甚至没有开始考虑这些事情)建立一些不变量:

  • 一些列表 students必须仅包含 Student对象(或隐式符合 Person 接口(interface)的对象,为了鸭子类型)。
  • 一些功能print_persons必须给出 Person 的列表对象并且只读取它
  • 一些功能add_person必须给出 Person 的列表对象并添加到其中

使用与静态语言相同的推理,您可以看到 print_persons(students)是正确的,而 add_person(students)可能不正确。

关于c# - Python 中的参数可以是逆变的还是协变的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21023176/

相关文章:

python - 培训YOLOv4-tiny

python - 是否可以阻止 python 终止直到 block 结束?

oop - 为什么类型推断对于面向对象的语言不切实际?

Clojure 静态类型,第 2 部分

c# - 创建一个 "dummy record"来强制数据库服从业务逻辑,是好主意还是愚蠢的主意?

c# - 如何判断水平滚动条是否显示在列表框上

Python:动态构建正则表达式的最佳实践

c++ - C++ 在多大程度上是一种静态类型语言?

c# - C# WPF 中的随机颜色

C# 获取 CSS 背景图像的完整 URL 链接