Python是强类型的吗?

Python是强类型的吗?,python,strong-typing,weak-typing,Python,Strong Typing,Weak Typing,我遇到过一些链接说Python是一种强类型语言 但是,我认为在强类型语言中,您无法做到这一点: bob = 1 bob = "bob" 我认为强类型语言不接受在运行时更改类型。也许我对强/弱类型的定义是错误的(或过于简单化) 那么,Python是强类型语言还是弱类型语言呢?让您感到困惑 我无法通过添加字符串'12'来更改1的类型,但我可以选择存储在变量中的类型,并在程序运行时更改该类型 动态类型的反面是静态类型;变量类型的声明在程序的生命周期内不会更改。强类型的反面是弱类型;值的类型可以在程序

我遇到过一些链接说Python是一种强类型语言

但是,我认为在强类型语言中,您无法做到这一点:

bob = 1
bob = "bob"
我认为强类型语言不接受在运行时更改类型。也许我对强/弱类型的定义是错误的(或过于简单化)

那么,Python是强类型语言还是弱类型语言呢?

让您感到困惑

我无法通过添加字符串
'12'
来更改
1
的类型,但我可以选择存储在变量中的类型,并在程序运行时更改该类型

动态类型的反面是静态类型;变量类型的声明在程序的生命周期内不会更改。强类型的反面是弱类型;值的类型可以在程序的生命周期内更改。

根据本文,Python是动态类型和强类型的(也提供了很好的解释)

也许您正在考虑的语言类型在程序执行期间不能更改,而类型检查在编译时发生以检测可能的错误


这个问题可能很有趣:这篇维基百科文章提供了更多的信息,Python是强动态类型的

  • strong键入表示值的类型不会以意外方式更改。只包含数字的字符串不会像Perl中可能发生的那样神奇地变成数字。每次类型更改都需要显式转换
  • 动态类型化意味着运行时对象(值)有一个类型,而静态类型则是变量有一个类型
至于你的例子

bob = 1
bob = "bob"
这是因为变量没有类型;它可以命名任何对象。在
bob=1
之后,您会发现
type(bob)
返回
int
,但在
bob=“bob”
之后,它返回
str
。(请注意,
type
是一个常规函数,因此它计算其参数,然后返回值的类型。)

这与旧的C语言形成对比,后者是弱静态类型,因此指针和整数几乎可以互换。(现代ISO C在许多情况下都需要转换,但默认情况下,我的编译器对此仍然很宽容。)

我必须补充一点,强类型和弱类型更像是一个连续统一体,而不是布尔选择。C++的类型比C(更需要转换)更强,但是可以使用指针转换来颠覆类型系统。

在动态语言(如Python)中,类型系统的强度实际上取决于其原语和库函数如何响应不同的类型。例如,
+
被重载,因此它可以处理两个数字或两个字符串,但不能处理一个字符串和一个数字。这是在实现
+
时做出的一种设计选择,但从语言的语义来看,这并不是必然的。事实上,当您在自定义类型上重载
+
时,您可以使它隐式地将任何内容转换为数字:

def至_编号(x):
“”“尝试将函数参数转换为浮点型对象。”“”
尝试:
返回浮动(x)
除了(TypeError、ValueError):
返回0
Foo类:
定义初始化(自身,编号):
self.number=number
定义添加(自身、其他):
将self.number+返回到_number(其他)
Foo
的实例可以添加到其他对象:

a=Foo(42) >>>a+“1” 43 >>>阿福 42 >>>a+1 43 >>>a+无 42
注意,即使强类型Python完全可以添加
int
float
类型的对象,并返回
float
类型的对象(例如,
int(42)+float(1)
返回
43.0
)。另一方面,由于类型之间的不匹配,如果尝试以下
(42::Integer)+(1::Float)
,Haskell会抱怨。这使得Haskell成为一种严格类型化语言,其中类型完全不相交,并且只能通过类型类进行受控形式的重载。

这已经被回答了好几次,但Python是一种强类型语言:

>>> x = 3
>>> y = '4'
>>> print(x+y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
这就是弱类型和强类型的区别。弱类型会根据上下文(例如Perl)自动尝试从一种类型转换为另一种类型。强类型从不隐式转换

您的困惑在于对Python如何将值绑定到名称(通常称为变量)的误解

在Python中,名称没有类型,因此可以执行以下操作:

bob = 1
bob = "bob"
bob = "An Ex-Parrot!"
名称可以绑定到任何内容:

>>> def spam():
...     print("Spam, spam, spam, spam")
...
>>> spam_on_eggs = spam
>>> spam_on_eggs()
Spam, spam, spam, spam
进一步阅读:

还有稍微相关但更高级的:


Python变量存储对表示该值的目标对象的非类型化引用

任何赋值操作都意味着将非类型化引用赋值给赋值对象,即对象通过原始引用和新(计数)引用共享

值类型绑定到目标对象,而不是引用值。(强)类型检查在执行具有该值的操作(运行时)时完成


换句话说,变量(从技术上讲)没有类型——如果想要精确的话,用变量类型来思考是没有意义的。但是引用是自动取消引用的,我们实际上是根据目标对象的类型来考虑的。

我认为,这个简单的例子应该解释强类型和动态类型之间的区别:

>>> tup = ('1', 1, .1)
>>> for item in tup:
...     type(item)
...
<type 'str'>
<type 'int'>
<type 'float'>
>>>

上述情况将在长时间内造成大型系统中无法维护代码的噩梦。随便你怎么说,但是“动态”改变变量类型的能力是个坏主意……

我认为所有现有答案都忽略了一些重要问题


弱类型意味着允许访问底层表示。在C中,我可以创建一个指针t
>>> tup = ('1', 1, .1)
>>> for item in tup:
...     type(item)
...
<type 'str'>
<type 'int'>
<type 'float'>
>>>
public static void main(String[] args) {
        int i = 1;
        i = "1"; //will be error
        i = '0.1'; // will be error
    }
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....
char sz[] = "abcdefg";
int *i = (int *)sz;
intptr_t i = (intptr_t)&sz;
char *spam = (char *)0x12345678
spam[0] = 0;
x = 'somestring'
x = 50
'foo' + 3 --> TypeError: cannot concatenate 'str' and 'int' objects
 'foo'+3 = 'foo3'
int x = 50;
x = 50
x = 50
x = 'now a string'