No hay ninguna razón especial . Python simplemente está aplicando su principio general de no realizar conversiones implícitas, que son causas bien conocidas de problemas, particularmente para los recién llegados, en lenguajes como Perl y Javascript.
int(some_string)
es una solicitud explícita para convertir una cadena a formato entero; las reglas para esta conversión especifican que la cadena debe contener una representación literal de entero válida. int(float)
es una solicitud explícita para convertir un flotante en un número entero; las reglas para esta conversión especifican que la porción fraccionaria del flotante se truncará.
Para int("3.1459")
poder regresar, 3
el intérprete tendría que convertir implícitamente la cadena en un flotante. Dado que Python no admite conversiones implícitas, elige generar una excepción en su lugar.
type(3)
devuelve<type int>
. Sin embargo, Python no se quejafloat("3")
. ¿Python no está convirtiendo implícitamente la cadena en un int y luego en un flotante?Es casi seguro que se trata de aplicar tres de los principios del Zen de Python :
Un porcentaje de las veces, alguien
int('1.23')
está llamando a la conversión incorrecta para su caso de uso y quiere algo comofloat
o en sudecimal.Decimal
lugar. En estos casos, es claramente mejor para ellos obtener un error inmediato que puedan corregir, en lugar de dar silenciosamente el valor incorrecto.En el caso de que usted no desea truncar que a un int, es trivial para hacer explícitamente pasándola a través de
float
primero, y luego llamando a uno deint
,round
,trunc
,floor
oceil
según el caso. Esto también hace que su código sea más autodocumentado, evitando que una modificación posterior "corrija" unaint
llamada hipotética truncada silenciosamente alfloat
dejar en claro que el valor redondeado es lo que desea.fuente
A veces, un experimento mental puede resultar útil.
int('1.23')
falla con un error. Este es el comportamiento existente.int('1.23')
produce1
sin error. Esto es lo que propones.Con el comportamiento A, es sencillo y trivial obtener el efecto del comportamiento B: utilícelo
int(float('1.23'))
en su lugar.Por otro lado, con el comportamiento B, obtener el efecto del comportamiento A es significativamente más complicado:
def parse_pure_int(s): if "." in s: raise ValueError("invalid literal for integer with base 10: " + s) return int(s)
(e incluso con el código anterior, no tengo total confianza en que no hay un caso de esquina que se maneje mal).
Por tanto, el comportamiento A es más expresivo que el comportamiento B.
Otra cosa a considerar:
'1.23'
es una representación de cadena de un valor de punto flotante. Conversión'1.23'
a un número entero conceptualmente implica dos conversiones (cadena a flotante a un entero), peroint(1.23)
yint('1')
cada implican sólo una conversión.Editar:
Y de hecho, hay casos extremos que el código anterior no manejaría:
1e-2
y1E-2
ambos son valores de punto flotante también.fuente
int('123E-2')
oint('1L')
.En palabras simples, no son la misma función.
Son 2 funciones diferentes con el mismo nombre que devuelven un número entero pero son funciones diferentes.
'int' es corto y fácil de recordar y su significado aplicado a cada tipo es intuitivo para la mayoría de los programadores, por eso lo eligieron.
No hay ninguna implicación de que estén proporcionando la misma funcionalidad o una combinación de funciones, simplemente tienen el mismo nombre y devuelven el mismo tipo. Podrían llamarse fácilmente 'floorDecimalAsInt' y 'convertStringToInt', pero eligieron 'int' porque es fácil de recordar, (99%) intuitivo y la confusión rara vez ocurre.
Analizar el texto como un número entero para el texto que incluye un punto decimal como "4.5" arrojaría un error en la mayoría de los lenguajes de computadora y se esperaría que arrojara un error para la mayoría de los programadores, ya que el valor de texto no representa un número entero e implica están proporcionando datos erróneos
fuente
int
es un tipo (y uno incorporado). Su creador (__new__
) toma varios tipos de argumentos posibles. Su comportamiento para cada tipo está bien definido.int
de hecho, no es una función sino un tipo, cuyos métodos__new__
y__init__
toman una cadena o un argumento flotante, tratando cada uno de ellos de manera apropiada. Sería más exacto decir que el tipo procesa los dos tipos de argumentos de manera diferente, pero solo hay unoint
.