2010-02-26 7 views
62

Gran parte de mi experiencia en programación está en Java, y todavía estoy haciendo la mayor parte de mi programación en Java. Sin embargo, estoy empezando a aprender Python para algunos proyectos paralelos en el trabajo, y me gustaría aprenderlo de forma independiente de mi fondo de Java, es decir, no quiero simplemente programar Java en Python. ¿Cuáles son algunas cosas que debería tener en cuenta?Como programador de Java aprendiendo Python, ¿qué debería buscar?

Un ejemplo rápido: al consultar el tutorial de Python, me encontré con el hecho de que los parámetros variables predeterminados de una función (como una lista) se conservan (se recuerda de llamada a llamada). Esto fue contra-intuitivo para mí como programador de Java y difícil de entender. (Consulte here y here si no entiende el ejemplo.)

Alguien también me proporcionó la lista this, que encontré útil, pero breve. Alguien tiene otros ejemplos de cómo un programador de Java podría tender a hacer mal uso de Python ...? ¿O cosas que un programador de Java asumiría falsamente o tendría problemas para entender?

Editar: Bien, una breve descripción de las razones abordadas por el artículo que he vinculado para evitar duplicados en las respuestas (como lo sugiere Bill the Lizard). (Por favor, avíseme si me equivoco al redactar, solo tengo solo iniciado con Python, por lo que es posible que no entienda todos los conceptos por completo. Y un descargo de responsabilidad: estos serán muy breves, así que si no entienden lo que se está haciendo a la salida del enlace.)

  • un método estático en Java no se traduce a una pitón classmethod
  • una sentencia switch en Java traduce en una tabla hash en Python
  • No use XML
  • Getters y setters son malvados (hey, soy j ust citando :))
  • La duplicación de código es a menudo un mal necesario en Java (p. la sobrecarga de métodos), pero no en Python

(Y si encuentras esta cuestión en todos interesantes, consulte el enlace de todos modos. :) Es bastante bueno.)

+2

Buena pregunta. El artículo al que se vinculó en el último párrafo es un muy buen comienzo. Puede considerar sacar un resumen (muy breve) de los puntos que figuran allí, solo para que las personas no dupliquen la misma lista en las respuestas. (Casi publiqué uno de los puntos en el artículo) –

+0

@Bill the Lizard - actualizado, gracias por la sugerencia. Solo por curiosidad, ¿en qué punto iba a publicar? :) – froadie

+1

Además, conviértalo en un Wiki de la comunidad. No hay "respuesta", solo muchos consejos. –

Respuesta

24
  • No ponga todo en las clases. La lista incorporada de Python y los diccionarios te llevarán lejos.
  • No se preocupe por mantener una clase por módulo. Divida los módulos por propósito, no por clase.
  • Usar herencia para el comportamiento, no interfaces. No cree una clase "Animal" para heredar de "Perro" y "Gato", solo para que pueda tener un método genérico "make_sound".

a hacer esto:

class Dog(object): 
    def make_sound(self): 
     return "woof!" 

class Cat(object): 
    def make_sound(self): 
     return "meow!" 

class LolCat(object): 
    def make_sound(self): 
     return "i can has cheezburger?" 
+5

Sé que me podría estar perdiendo algo simple ... pero ¿puede explicar más el "por qué" detrás de su último punto? – froadie

+4

@froadie: No es que tener una clase de Animal sea malo, es solo que es completamente innecesario a menos que quieras proporcionar una implementación predeterminada de make_sound(). – dsimcha

+0

Hmmmm. Pero, ¿el polimorfismo está disponible en Python? ¿Sería eso una razón/justificación ...? (Y creo que la próxima pregunta va a ser: ¿cuánto de esto, una vez que aprende, debe revertirse a cómo se programa Java? :)) – froadie

9

El más grande que puedo pensar es no entendiendo o no utilizando completamente la tipificación de pato. En Java, debe especificar información de tipo muy explícita y detallada por adelantado. En Python, la tipificación es tanto dinámica como implícita. La filosofía es que debes pensar en tu programa en un nivel más alto que los tipos nominales. Por ejemplo, en Python, no se usa la herencia para sustituir el modelo. La sustituibilidad viene por defecto como resultado de tipado de pato. La herencia es solo una conveniencia del programador para reutilizar la implementación.

De manera similar, el modismo pitónico es "perdón, no pidas permiso". La escritura explícita se considera malvada. No verifique si un parámetro es un cierto tipo por adelantado. Intenta hacer lo que necesites con el parámetro. Si no se ajusta a la interfaz adecuada, arrojará una excepción muy clara y podrá encontrar el problema muy rápidamente. Si alguien pasa un parámetro de un tipo nominalmente inesperado pero que tiene la misma interfaz que usted esperaba, entonces ha obtenido flexibilidad de forma gratuita.

+0

Wow. No creo entender mucho del primer párrafo. Supongo que buscaré en Google algunos de esos términos e investigaré cómo Python los usa :) Gracias – froadie

+0

Ok - Estoy investigando, y estoy descubriendo que me está empujando en una dirección similar a la del tercer punto de Ryan. Esta puede ser una pregunta muy simple para cualquier persona con experiencia en Python, pero ¿qué papel juega el polimorfismo en Python? – froadie

+1

Python tiene polimorfismo infinito. Siempre que un objeto dado tenga un campo o método requerido, en tiempo de ejecución, en esa línea de código, se ejecutará el código. En otras palabras, ese objeto no necesita tener ese campo o método declarado por adelantado, pero puede agregarse al objeto más adelante si lo desea. El polimorfismo no depende de la herencia, porque el tipado de pato evita por completo el requisito de tiempo de compilación. –

13

Una cosa que pueda ser utilizada en Java que usted no encontrará en Python es estricta privacidad. Esto no es tanto algo a tener en cuenta ya que es algo que no buscar (me avergüenza cuánto tiempo busqué un Python equivalente a 'privado' cuando comencé!). En cambio, Python tiene mucha más transparencia y una introspección más fácil que Java. Esto cae bajo lo que a veces se describe como la filosofía de "todos estamos consintiendo adultos aquí". Hay algunas convenciones y mecanismos de lenguaje para ayudar a prevenir el uso accidental de métodos "no públicos" y demás, pero la mentalidad de ocultar información prácticamente no existe en Python.

+6

Así que, básicamente, parece Para mí, un tema recurrente al comparar Java con Python es que Python confía mucho más en ti: te da mucha más potencia, pero también una capacidad mucho mayor para complicar las cosas. – froadie

+0

Lo mismo en lo de búsqueda. Pasé buena parte de mis primeros días buscando un equivalente privado. –

+3

La frase clave de Python es "Todos somos adultos aquí". Python se distribuye como fuente. ¿Qué significa "privado" cuando puedes leer la fuente? Si es necesario, solo edita la fuente para cambiar las cosas. –

6

Lo más importante, desde un punto de vista de Java, es que está perfectamente bien no hacer clases para todo. Hay muchas situaciones donde un enfoque de procedimiento es más simple y más corto.

Lo siguiente más importante es que tendrá que superar la noción de que el tipo de un objeto controla lo que puede hacer; más bien, el código controla qué objetos deben ser capaces de soportar en el tiempo de ejecución (esto es en virtud de pato-tipado).

Ah, y usa listas y dicts nativos (no descendientes personalizados) en la medida de lo posible.

5

La forma en que se tratan las excepciones en Python es diferente de cómo se tratan en Java. Mientras que en Java el consejo es usar excepciones solo para condiciones excepcionales, esto no es así que con Python.

En Python cosas como Iterator hacen uso de un mecanismo de excepción para indicar que no hay más elementos. Pero tal diseño no se considera una buena práctica en Java.

Como Alex Martelli pone en su libro Python in a Nutshell el mecanismo de excepción con otras lenguas (y aplicable a Java) es LBYL (mirar antes de saltar): es comprobar de antemano, antes de intentar una operación, todas las circunstancias que pueden hacer que la operación no sea válida.

Donde como con Python es el enfoque EAFP (que es más fácil pedir perdón que permiso)

1

Un corolario de "No usar clases para todo": devoluciones de llamada.

La forma de Java para hacer devoluciones de llamada se basa en pasar objetos que implementan la interfaz de devolución de llamada (por ejemplo ActionListener con su método actionPerformed()).Nada de este tipo es necesaria en Python, puede pasar directamente a métodos o incluso funciones definidas a nivel local:

def handler(): 
    print("click!") 
button.onclick(handler) 

O incluso lambdas:

button.onclick(lambda: print("click!\n")) 
+2

-1 - ejemplo lambda pobre. lambda está destinado a contener una sola * expresión *, no enunciado, y devuelve el valor de esa expresión. Su ejemplo lambda, mientras funciona, en realidad está devolviendo el valor devuelto al llamar a impresión (que es None, creo). Si tuviera una lambda que necesitara imprimir 2 declaraciones, ¿le diría a un novato que escriba 'lambda: imprimir (" primera línea ") o imprimir (" segunda línea ")'? – PaulMcG

22

El artículo de referencia tiene un buen consejo que puede ser fácilmente malinterpretado e incomprendido. Y algunos malos consejos.

Deje atrás a Java. Empezar de nuevo. "no confíes en tus instintos [basados ​​en Java]". Decir que las cosas son "contra-intuitivas" es un mal hábito en cualquier disciplina de programación. Cuando aprendas un nuevo idioma, comienza de nuevo y abandona tus hábitos. Su intuición debe estar equivocado.

Los idiomas son diferente. De lo contrario, serían del mismo idioma con una sintaxis diferente, y habría traductores simples. Debido a que no hay traductores simples, no hay un mapeo simple. Eso significa que la intuición es inútil y peligrosa.

  • "Un método estático en Java no se traduce en un método de clase Python". Este tipo de cosas es realmente limitado e inútil. Python tiene un decorador staticmethod. También tiene un decorador classmethod, para el cual Java no tiene equivalente.

    Este punto, por cierto, también incluye el consejo mucho más útil sobre no envolver innecesariamente todo en una clase. "La traducción idiomática de un método estático de Java es generalmente una función de nivel de módulo".

  • La instrucción Java switch en Java se puede implementar de varias maneras. En primer lugar, y ante todo, generalmente es una construcción if elif elif elif. El artículo es inútil a este respecto. Si está absolutamente seguro de que esto es demasiado lento (y puede demostrarlo), puede usar un diccionario de Python como un mapeo ligeramente más rápido de un valor a un bloque de código. Cambiar a ciegas el cambio al diccionario (sin pensar) es realmente un mal consejo.

  • No utilice XML. No tiene sentido cuando se saca de contexto. En contexto, significa no confiar en XML para agregar flexibilidad. Java se basa en describir cosas en XML; Los archivos WSDL, por ejemplo, repiten información que es obvia al inspeccionar el código. Python se basa en la introspección en lugar de repetir todo en XML.

    Pero Python tiene excelentes bibliotecas de procesamiento XML. Varios.

  • Getters y setters no son requeridos en Python de la forma que se requieren en Java. En primer lugar, tiene una mejor introspección en Python, por lo que no necesita getters y setters para ayudar a crear objetos bean dinámicos. (Para eso, usa collections.namedtuple).

    Sin embargo, tiene el decorador property que agrupará getters (y setters) en una construcción similar a un atributo. El punto es que Python prefiere atributos desnudos; cuando sea necesario, podemos agrupar getters y setters para que aparezcan como si hubiera un atributo simple.

    Además, Python tiene clases de descriptor si las propiedades no son lo suficientemente sofisticadas.

  • La duplicación de código a menudo es un mal necesario en Java (por ejemplo, sobrecarga de métodos), pero no en Python. Correcto. Python usa argumentos opcionales en lugar de sobrecarga de métodos.

    La viñeta pasó a hablar sobre el cierre; eso no es tan útil como el simple consejo de usar valores de argumento predeterminados sabiamente.

+0

Aunque no está de acuerdo con algunos de los elementos aquí, el consejo sobre "namedtuple" fue tan útil que ganó un voto positivo. – javadba

+0

@ S.Lott Quiero comenzar de nuevo, pero realmente no quiero tener que aprender cosas como lo que es una cadena, int, etc. ¿Tiene alguna sugerencia sobre libros o sitios para alguien que las hormigas de aprender Python desde cero, pero ya tiene experiencia en programación? – Abdul

Cuestiones relacionadas