为什么“int + string”在静态类型的 C# 中是可能的,但在动态类型的 Python 中却不行

本文关键字:类型 动态 Python int string 为什么 静态类 静态 | 更新日期: 2023-09-27 18:36:48

在学习C#时,我发现这真的很奇怪,动态类型的Python会在以下代码中引发错误:

i = 5
print i + " "

而静态类型的 C# 通常会执行类似的代码:

int i = 5;
Console.Write(i + " ");

我希望有其他方法(在python中,我可以在没有任何强制转换的情况下做到这一点,但是C#需要我将int转换为字符串或字符串转换为int)。

只是为了强调,我不是在问哪种语言更好,我很好奇以这种方式实现语言背后的原因是什么。

为什么“int + string”在静态类型的 C# 中是可能的,但在动态类型的 Python 中却不行

你是对的,这里有些奇怪。 奇怪的是,+在任何一种语言中都意味着字符串连接! +是否可以将 int 连接到字符串上,与+的意思是"连接"的奇怪相比,这是一个小问题。

我不知道哪种语言首先允许使用+来表示字符串连接,但是这种错误功能已经一遍又一遍地重复,以至于现在我们通常甚至没有注意到它是多么奇怪。让我们列出正常加法的一些属性,看看字符串是否合适。

  • 加法是可交换的,但字符串连接不是。 x + y != y + x
  • 加法是关联的,但 C# 中的字符串连接不是。 (x + y) + z 不需要等于 x + (y + z),如果 y 和 z 是整数。
  • 加法与反运算(减法)配对,其性质是,如果 x + y 是 z,则 z - y 是 x。字符串没有这样的操作。
  • 加法具有左恒等式和右恒等式,字符串连接也是如此。(空字符串)。

四分之一不好。字符串连接与加法非常不同,那么它们为什么要共享一个运算符呢?

我不经常这样说,但C做对了。字符串连接运算符应该是:连接。在 C 中,"X" "Y" 表示"XY" 。如果将两个字符串文本并排放置,它们将连接成第三个字符串文本。

这不是一个静态/动态的问题,而是一个语言设计哲学的问题。

在 Python 中,+被定义为数字的加法和字符串的串联。如果你有一点编程经验,这是完全合理的行为。

但是,当您拥有其中之一时,会发生什么?它是尝试将字符串转换为数字,还是将数字转换为字符串?对于任何做过任何编程的人来说,这两种行为都是完全合理的,但是由于不同的语言对这种情况的发生方式有不同的规则,你可能会做出与其他人不同的假设,这取决于你已经使用过的语言。

Python的指导原则之一是"显式优于隐式"(import this),因此它使您明确声明所需的行为。如何?当然,通过将字符串或数字转换为所需的类型。然后它们都是字符串或两个数字,行为很明显。

生成的代码更容易阅读(即使你不太了解Python),因为你不必猜测它会做什么。

这不是静态类型与动态类型之间的真正领域。相反,它是类型与类型(至少根据一些常用的术语,维基百科恰好也在其编程语言的特征中使用)。C#和Python都是强类型(根据这个定义)。

不幸的是,所有这些概念都不是非黑即白的,而是灰度的,而且定义不清。然而,结果是,一种语言执行类型检查的强度以及它执行检查存在细微差别。

碰巧的是,在您的特定情况下,C# 会重载字符串和数字(实际上是任意对象)的operator +,而 Python 不会。在这种情况下,这可以说使Python稍微严格一些。

对于 C#,有一个名为 ToString() 的方法用于 Int32 (int) 和几乎所有类型 - 指针类型在这种情况下是例外。

C# 中的 String 类重载了 + 运算符,在这种情况下,该运算符仅调用 String.Concat(Object, Object)。

在我看来,这更多的是.NET Framework工作的结果,而不是其他任何东西。

了解 python 数据模型 (http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types) 将在这里对您有所帮助。

当你执行a + b时,这被转换为幕后a.__add__(b)。这就是python支持运算符重载的方式,因为缺乏静态类型。

C#允许通过ToString()方法隐式强制转换到字符串;python没有任何隐式转换的概念。这是有效的,因为 ToString() 是在每个对象上定义的方法,而 C# 具有静态类型,因此调用者在何时要强制转换他们的对象是显而易见的。

如果要查看此行为的实际效果,可以运行以下命令(但不要在生产中执行此操作):

class MyString(str):
    def __add__(self, other):
        """ automatically concatenate other values as strings """
        return super(MyString, self).__add__(str(other))
s = MyString("this is a string")
print s + 1

当然,如果您查看上面的转换,您将遇到麻烦 print 1 + s .我建议明确你的类型转换,即使只是转换为字符串,因为边缘情况会让你发疯。

动态类型在这里并没有真正发挥作用,两种语言都明白 i 是一个 int,而 " " 是一个字符串。不同之处在于C#有一个函数+,它接受(int,string)参数,而Python没有。