Python中的参数可以是对立的还是协变的?

时间:2014-01-09 14:38:31

标签: c# python static-typing dynamic-typing

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

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

如果我没有误会,那么在编译时用C#这样的语言检查逆变和协方差之类的东西,这是可能的,因为变量有一个类型,它绑定的值也有一个类型,这些必须匹配或是co(ntra) - 或不变的。但是,由于在编译时没有使用像Python这样的语言进行打字的概念,我不知道如何应用这个概念。

有什么想法吗?

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

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

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

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

现在,在Python中,我们可以很好地传递一个Bird对象,该对象在继承层次结构中不会以任何方式与Person相关(除了它也会从对象继承),只要这只鸟实现{{1 }}

这就是我问这个概念的原因。根据我的理解,Python是协变的和逆变的..好吧,一切?

1 个答案:

答案 0 :(得分:3)

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

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

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

  • 某些列表students必须只包含Student个对象(或隐含符合Person接口的对象,以便进行鸭子输入。)
  • 必须为某个函数print_persons提供Person个对象的列表并且只读取它
  • 必须为某个函数add_person提供Person个对象的列表并添加到其中

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