在Python中,int('123')是'int'类的构造函数调用还是函数调用?

4
我正在学习Python,但是对于Python的数据类型有些困惑。我一直在阅读这句话:

'Python中的所有对象都是对象'


这包括整数、浮点数、字符串、集合、列表等。当我们像这样写:[1,2,3]时,我们实际上创建了一个list类的对象(是这样吗?)。那么,当我们写一个整数如123时,它意味着它是int类的对象吗?但是,在书中我们阅读到要将字符串转换为整数需要使用int方法?
但是我认为int是一个类,也接受构造函数中的字符串对象,然后我们获得整数对象,对吧?
那么,在Python中int是一个方法还是一个类呢?

1
在Python解释器中尝试使用help(int)。它是一个类。 - user94559
谢谢smarx,我明白了:) 我是个初学者,两个术语让我感到困惑 :) - Vikram Chhipa
注意:1"x"等均为字面量。 - Karoly Horvath
2个回答

9

是的,int 是一个类(也被称为类型;请参见Python:术语“class”与“type”),执行 int('123') 返回一个 int 对象的实例。

但是,在标准 Python(即 CPython)中,对于小整数(范围在 -5 到 256 之间,包括两个端点),int 构造函数实际上并不会构建一个新的整数对象。出于效率原因,解释器有一个小整数缓存,构造函数只是返回对现有 int 对象的引用。这个主题在 “is” operator behaves unexpectedly with integers 的答案中讨论过。

你的书中将 int() 称为“int 方法”,我认为有点粗心大意。严谨地说,int 本身是一个类,是一个可调用对象,当你调用一个类时,这个调用会自动转换为对类的构造方法(即其 __new__ 方法)的调用。但非正式地,通常将 int() 称为函数调用或方法调用。

我差点忘了你第一段中的问题。当我们写

[1, 2, 3]

解释器创建了3个int对象并将它们放在一个新的list实例中。(更准确地说,它将对int对象的引用放入列表中。)
使用标准的dis模块,您可以反汇编此操作的字节码:
from dis import dis
dis('a=[1,2,3]')    

输出

  1           0 LOAD_CONST               0 (1)
              3 LOAD_CONST               1 (2)
              6 LOAD_CONST               2 (3)
              9 BUILD_LIST               3
             12 STORE_NAME               0 (a)
             15 LOAD_CONST               3 (None)
             18 RETURN_VALUE

因此,即使我们“只是”创建了一个字面上的列表,它仍然是一个完整的list实例对象。与一些面向对象编程语言不同,Python没有任何不是对象的“原始”数据类型,因此字面意义上的整数和字符串也是对象。因此,字面意义上的字符串配备了所有标准的字符串方法。例如,
print('hello'.lower)

输出

built-in method lower of str object at 0xb72e7880>

这段代码向我们展示了字符串 'hello' 具有标准的 lower() 方法。


仅仅是一个小错误(依照我的看法):解释器创建了3个整型对象,并将它们放到一个新的列表实例中。 它并不是把对象放在列表内,而是保留了对象的引用放在列表里。 - Pranjal Kumar
@PranjalKumar 我已经更新了我的答案。我最初没有提到引用,因为在Python中我们总是使用对象引用,并且讨论这个话题需要另一个问题。 ;) - PM 2Ring
你知道为什么在使用文字和类时,反汇编结果会不同吗?例如,dis("x = 1000") 和 dis("x = int(1000)") 的结果是不同的。 - IKnewThat
@IKnewThat 为什么不能不同呢?如果你的代码要求调用 int(1000),那么解释器就会执行该调用并返回结果。虽然 int(1000) 通常会调用内置的 int 构造函数,但也有可能“遮蔽”该内置名称。例如,考虑一下如果你这样做 int = str; x = int(1000) 会发生什么。 - PM 2Ring

2
正如您在Python文档中阅读的那样。

class int(x,base = 10)从数字或字符串x构造整数对象,如果没有给出参数,则返回0。 如果x是数字,则可以是普通整数,长整数或浮点数。 如果x是浮点数,则转换截断为零。 如果参数超出整数范围,则函数返回一个长对象。

因此,它是一个类构造函数,根据给定的输入x构造一个int对象。

谢谢DJanssens :),所以当我们创建数据类型字面量时,实际上是在创建它们类的对象?例如:x = [],那么x就是一个列表类的对象?对吧,在其他数据类型中也是这样,因为这就是为什么我们可以调用它们的方法,比如x.index('aa')。 - Vikram Chhipa
是的@vikram,有些对象被频繁创建,因此为其创建了一个字面量。因此,您可以执行x = 3,这将在幕后创建一个int对象。对于列表和任何其他Python类型也是如此。 - DJanssens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接