我遇到过一些链接,上面说Python是一种强类型语言。
然而,我认为在强类型语言中你不能这样做:
bob = 1
bob = "bob"
我认为强类型语言在运行时不接受类型更改。也许我对强/弱类型的定义是错误的(或过于简单)。
那么,Python是强类型语言还是弱类型语言呢?
我遇到过一些链接,上面说Python是一种强类型语言。
然而,我认为在强类型语言中你不能这样做:
bob = 1
bob = "bob"
我认为强类型语言在运行时不接受类型更改。也许我对强/弱类型的定义是错误的(或过于简单)。
那么,Python是强类型语言还是弱类型语言呢?
当前回答
Python是强类型的,因为它没有未检查的动态类型错误。换句话说,您不能违反它的类型系统。
定义
Type: set of values. It partially defines the intended usage (behaviour) of its values. It can be specified in extension with an enumeration or in intension with a predicate. Type system: system checking that values are used as intended, avoiding undefined behaviour partially. Undefined behaviour should be avoided because it can lead to late program crash or silent loss of data and production of incorrect results. Typed language: language with a type system. Type error: program error checkable by a type system. Expression: program text denoting a value. Static/dynamic type: compile-time/run-time type of an expression. The run-time type of an expression is the type of the value that it denotes. Static/dynamic type system: type system checking static/dynamic types. Statically/dynamically typed language: language with a static/dynamic type system. Static/dynamic type error: program error checkable by a static/dynamic type system. Weakly/strongly typed language: language with/without unchecked dynamic type errors. Statically typed, dynamically typed, or both imply strongly typed. Monomorphic/polymorphic expression: expression having a single dynamic type/multiple dynamic types. A monomorphic expression has single intended usage, and a polymorphic expression has multiple intended usage. Universal/ad-hoc polymorphic expression: real/virtual polymorphic expression. A real polymorphic expression denotes a single value that has multiple types, and a virtual polymorphic expression denotes multiple values that have single types. Parametric/inclusion polymorphic expression: universal polymorphic expression based on generic types/subtypes of a type (e.g. the C++ expression & denotes a single T* (T&) operator value where T is a generic type/the C++ expression std::exception denotes a single S class value where S is a generic subtype of std::exception). Overloading/coercion polymorphic expression: ad-hoc polymorphic expression based on expression/value conversion (e.g. the C++ expression + denotes int (int&, int&) and float (float&, float&) operator values/the C++ expression 3.5 denotes float and bool values).
参考
Cardelli (Luca), Wegner (Peter),“关于理解类型,数据抽象和多态性”,计算调查,第17卷,第4期,1985,第471-523页,DOI: https://doi.org/10.1145/6041.6042。
其他回答
Python是强动态类型的。
强类型意味着值的类型不会以意外的方式改变。只包含数字的字符串不会像Perl中那样神奇地变成数字。每次类型更改都需要显式转换。 动态类型意味着运行时对象(值)具有类型,而静态类型中变量具有类型。
至于你的例子
bob = 1
bob = "bob"
这是因为变量没有类型;它可以命名任何对象。在bob=1之后,你会发现type(bob)返回int,但在bob="bob"之后,它返回str。(注意,type是一个常规函数,所以它计算其参数,然后返回值的类型。)
与此相比,老式的C语言是弱静态类型的,因此指针和整数几乎是可以互换的。(现代ISO C在很多情况下需要转换,但我的编译器在默认情况下仍然很宽容。)
我必须补充一点,强类型和弱类型更多的是一个连续体,而不是一个布尔选择。c++具有比C更强的类型(需要更多的转换),但类型系统可以通过使用指针强制转换来颠覆。
在动态语言(如Python)中,类型系统的强度实际上取决于其原语和库函数对不同类型的响应方式。例如,+是重载的,所以它对两个数字或两个字符串有效,而不是一个字符串和一个数字。这是在实现+时做出的设计选择,但从语言的语义来看并不是必须的。事实上,当你在自定义类型上重载+时,你可以让它隐式地将任何东西转换为数字:
def to_number(x):
"""Try to convert function argument to float-type object."""
try:
return float(x)
except (TypeError, ValueError):
return 0
class Foo:
def __init__(self, number):
self.number = number
def __add__(self, other):
return self.number + to_number(other)
类Foo的实例可以添加到其他对象:
>>> a = Foo(42)
>>> a + "1"
43.0
>>> a + Foo
42
>>> a + 1
43.0
>>> a + None
42
请注意,尽管强类型Python完全可以添加int和float类型的对象,并返回float类型的对象(例如,int(42) + float(1)返回43.0)。另一方面,由于类型之间的不匹配,如果尝试以下(42::Integer) + (1:: Float), Haskell会抱怨。这使得Haskell成为一种严格的类型语言,其中类型是完全不相连的,并且只能通过类型类进行受控的重载。
我认为,这个简单的例子可以解释强类型和动态类型之间的区别:
>>> tup = ('1', 1, .1)
>>> for item in tup:
... type(item)
...
<type 'str'>
<type 'int'>
<type 'float'>
>>>
java:
public static void main(String[] args) {
int i = 1;
i = "1"; //will be error
i = '0.1'; // will be error
}
现有的答案大多同意Python是一种强类型语言,因为它不会隐式地将值从一种类型转换为另一种类型。这些答案提到了将字符串添加到整数的情况来支持这种说法;"foo" + 3在Python中引发TypeError,而在Javascript(通常被认为是弱类型语言)中,数字3隐式转换为字符串,然后连接,因此结果是字符串"foo3"。
但在其他一些情况下,Python确实会执行隐式类型转换:
# implicit conversion from int to float
1 + 1.0
# implicit conversion from list to bool
if []: pass
相比之下,f#(通常被认为是强类型语言)不允许这两种:
1 + 1.0;;
----^^^
error FS0001: The type 'float' does not match the type 'int'
if [] then 1 else 2;;
---^^
error FS0001: This expression was expected to have type bool but here has type 'a list
因此,“强类型”和“弱类型”语言并没有严格的二分法,相反,我们可以说Python比Javascript更强类型,但没有f#强类型。
class testme(object):
''' A test object '''
def __init__(self):
self.y = 0
def f(aTestMe1, aTestMe2):
return aTestMe1.y + aTestMe2.y
c = testme #get a variable to the class
c.x = 10 #add an attribute x inital value 10
c.y = 4 #change the default attribute value of y to 4
t = testme() # declare t to be an instance object of testme
r = testme() # declare r to be an instance object of testme
t.y = 6 # set t.y to a number
r.y = 7 # set r.y to a number
print(f(r,t)) # call function designed to operate on testme objects
r.y = "I am r.y" # redefine r.y to be a string
print(f(r,t)) #POW!!!! not good....
在一个大型系统中,上述情况会在很长一段时间内造成代码不可维护的噩梦。随便你怎么称呼它,但“动态”改变变量类型的能力只是一个坏主意……
术语“强类型”没有明确的定义。
因此,这个词的使用取决于你和谁说话。
我不认为任何没有显式声明变量类型或没有静态类型的语言是强类型的。
强类型不只是排除转换(例如,“自动”将整数转换为字符串)。它排除了赋值(即改变变量的类型)。
如果以下代码编译(解释),则该语言不是强类型的:
Foo = 1 Foo = "1"
在强类型语言中,程序员可以“依赖”类型。
例如,如果程序员看到声明,
UINT64 kZarkCount;
并且他或她知道20行之后,kZarkCount仍然是UINT64(只要它出现在同一个块中)——而不必检查中间的代码。