Python的内置函数int是否仍会尝试转换提交的值,即使该值已经是整数?
更简洁:转换算法导致int('42')
和int(42)
之间有任何性能差异吗?
答案 0 :(得分:10)
这在函数long_long
in Objects/longobject.c
中处理,详见thefourtheye:
static PyObject *
long_long(PyObject *v)
{
if (PyLong_CheckExact(v))
Py_INCREF(v);
else
v = _PyLong_Copy((PyLongObject *)v);
return v;
}
因此,当参数已经是int
时,引用计数会递增并返回相同的对象。
一般来说,您可以为不可变类型假设类似的行为。例如,tuple(mytuple)
会返回对mytuple
的新引用,相反,list(mylist)
会创建mylist
的副本。
答案 1 :(得分:6)
如果将int
对象传递给int()
,则会得到相同的对象(CPython 3.3.2):
>>> a = 1000 * 1000 # large enough to avoid interning
>>> b = int(a)
>>> a is b
True
我不知道“算法性能差异”是什么意思,但它不会创建新对象。
答案 2 :(得分:5)
根据comments in the source code,
将数字或字符串转换为整数,如果没有参数则返回0 给出。如果x是数字,则返回
x.__int__
()。对于浮点 数字,这会截断为零。如果x不是数字或者给出了base,那么x必须是一个字符串, bytes或bytearray实例,表示中的整数文字 给定基数
因此,如果输入是一个数字,将在该对象上调用__int__
函数,并返回结果。内部nb_int
is an item in PyNumberMethods structure,对应__int__
函数。根据撰写本文时的最新源代码long_long
is the function which corresponds to the nb_int
function,其定义如下
long_long(PyObject *v)
{
if (PyLong_CheckExact(v))
Py_INCREF(v);
else
v = _PyLong_Copy((PyLongObject *)v);
return v;
}
这里PyLong_checkExact
是一个宏,它只检查当前对象是否真的是long类型。如果是真的,它只是增加引用计数并按原样返回对象,不会做任何额外的事情。
如果输入是字符串形式,则必须将字符串转换为具有PyLong_FromUnicodeObject
函数的数字。
答案 3 :(得分:1)
为什么不直接比较两者?
>>> def f(): int('42')
...
>>> def g(): int(42)
...
>>> from timeit import timeit
>>> timeit(f)
0.3384080480027478
>>> timeit(g)
0.2566616949989111