2010-03-15 16 views
5

Disculpe si esto es bastante noobish para usted, pero estoy empezando a aprender Python después de aprender C++ & Java, y me pregunto cómo en el mundo podría declarar variables como id = 0 y name = 'John' sin ninguna int o string está en frente! Me di cuenta de que tal vez es porque no hay ' en un número, pero ¿cómo podría Python darse cuenta de algo así como def increase(first, second) en lugar de algo como int increase(int first, int second) en C++ ?!¿Cómo diferencia Python entre los diferentes tipos de datos?

+2

Solo una sugerencia: no nombre sus variables como "id", anulará la función incorporada id(). En Python, las funciones son objetos de primera clase, por lo que comparten el espacio de nombres con las variables. –

+0

Gracias! Lo tendré en cuenta – wrongusername

+0

Una cosa que aprendí de python :: boost es que todo, quiero decir __everything__ en Python es del tipo Object (objeto de Python). Así es como es posible que un int pueda ser string o char o float o lo que sea, es todo un objeto y se maneja de esa manera. str, int, etc. son solo derivados de un objeto y, por lo tanto, pueden transformarse. –

Respuesta

13

Los objetos literales que mencionas llevan (punteros a ;-) sus propios tipos con ellos, por supuesto, así que cuando un nombre está vinculado a ese objeto no surge el problema del tipo - el objeto siempre tiene un tipo, el el nombre no lo hace, simplemente lo delega al objeto al que está vinculado.

No hay "averiguar" en def increase(first, second): - nombrar increase consigue unido a un objeto de función, nombres first y second se registran como parámetros de nombres y conseguirá determinada (muy posiblemente a objetos de tipos diferentes en varios puntos) como increase se llama.

Así que dicen que el cuerpo es return first + second - una llamada a increase('foo', 'bar') entonces encantaría volver 'foobar' (delegando la adición a los objetos, que en este caso son cadenas), y tal vez más tarde una llamada a increase(23, 45) será tan feliz volver 68 - otra vez al delegar la adición a los objetos vinculados a esos nombres en el punto de llamada, que en este caso son enteros. Y si llama con tipos incompatibles obtendrá una excepción ya que la operación de adición delegada no puede dar sentido a la situación, ¡no es gran cosa!

+0

¡Gracias tanto a usted como a todos los que contribuyeron! :) – wrongusername

+0

+1 Esta es una gran respuesta. –

4

Cuando se trata de la asignación de valores a las variables literales, el tipo del valor literal se puede inferir en el momento del análisis léxico. Por ejemplo, cualquier cosa que coincida con la expresión regular (-)?[1-9][0-9]* puede inferirse que es un literal entero. Si desea convertirlo a un carro flotante, debe haber un molde explícito. Del mismo modo, un literal de cadena es cualquier secuencia de caracteres encerrados en comillas simples o dobles.

En una llamada a método, los parámetros no están verificados por tipo. Solo necesita ingresar el número correcto de ellos para poder llamar al método. Siempre que el cuerpo del método no cause ningún error con respecto a los argumentos, puede llamar al mismo método con muchos tipos diferentes de argumentos.

+0

+1 Para "análisis léxico": ¡conciso y correcto! –

+0

(Por supuesto, las reglas reales de análisis léxico para el análisis son un poco más complicadas que esto.) –

+0

Además, para ser pedante, '(-)? [1-9] [0-9] *' sería lo que a * decimal * entero literal se parece a. –

0

En Python, a diferencia de C++ y Java, los números y las cadenas son ambos objetos. Así que esto:

id = 0 
    name = 'John' 

es equivalente a:

id = int(0) 
    name = str('John') 

Como las variables id y name son referencias que pueden hacer frente a cualquier objeto de Python, que no deben ser declarado con un tipo particular.

+0

¿Por qué el voto a favor? – wrongusername

+1

Hay algunas cosas engañosas acerca de esta publicación. 1) Es cierto que ints y strs son objetos en Python y C++ y Java tienen algunos tipos primitivos además de objetos, pero no es por eso que no tiene que declarar variables en Python. 2) El código equivalente sería 'id = int (0)' y 'name = str ('John')'; 'Number' y' String' no son los nombres de nada en Python, y realmente no aclara nada para reformular tales cosas, teniendo en cuenta que esto aún requiere la creación de objetos 'int' y' str' a partir de literales. 3) "punteros de objeto" no es un término técnico en el contexto de Python AFAIK –

+0

Gracias Mike! :) – wrongusername

7

Python es tipado dinámicamente: todas las variables pueden hacer referencia a un objeto de cualquier tipo.id y name pueden ser cualquier cosa, pero los objetos reales son de tipos como int y str. 0 es un literal que se analiza para hacer un objeto int y 'John' un literal que crea un objeto str. Muchos tipos de objetos no tienen literales y se devuelven por un exigible (como frozenset -No hay manera de hacer una frozenset literal, debe llamar frozenset.)

En consecuencia, no hay tal cosa como la declaración de variables, ya que se no están definiendo nada sobre la variable. id = 0 y name = 'John' son solo asignación.

increase devuelve int porque eso es lo que devuelve; nada en Python lo obliga a no ser ningún otro objeto. first y second son solo ints si los hace así.

Los objetos, hasta cierto punto, comparten una interfaz común. Puede utilizar los mismos operadores y funciones en todos ellos, y si son compatibles con esa operación en particular, funciona. Es una técnica común y recomendable utilizar diferentes tipos que se comporten de forma similar de forma intercambiable; esto se llama pato escribiendo. Por ejemplo, si algo toma un objeto file, puede pasar un objeto cStringIO.StringIO, que admite el mismo método que un archivo (como read y write), pero es un tipo completamente diferente. Esto es algo así como las interfaces de Java, pero no requiere ningún uso formal, solo define los métodos apropiados.

+0

¡Gracias! Te recomiendo totalmente, pero desafortunadamente mi límite diario de votos ha sido alcanzado. – wrongusername

Cuestiones relacionadas