9 rarezas de Python para programadores de C++

9 rarezas de Python para programadores de C++

@programacion
https://unsplash.com/photos/RDolnHtjVCY

Python puede llamarse un lenguaje de programación extraño.

Al menos cuando estás migrando desde otros lenguajes como C, C++, C#, Java, PHP o JavaScript. Todos estos lenguajes siguen una sintaxis típica y comparten muchos principios operativos. Por supuesto, también puede encontrar la mayoría de estos principios en Python, pero al hacerlo, rompe los patrones de muchos de ellos. A veces conduce a lo mejor ya veces a lo peor. Entre los 5 principales lenguajes de programación de TIOBE , Python es el único que no utiliza la sintaxis de llaves estilo C.

Estaba trabajando para convertir una Raspberry Pi en una cámara web, durante la cual tuve que implementar un servidor en Python, porque la mejor API para interactuar con la cámara de Pi está escrita en él. Ya había usado Python varias veces antes, pero era el proyecto más grande, y pronto no solo recordé algunas de sus rarezas, sino que también descubrí otras nuevas.

1. Espacios

Cuando la gente me pregunta por qué no me gusta Python, siempre nombro los espacios primero. Cuando el flujo de ejecución del programa está controlado únicamente por ellos, surgen dos problemas. El primero es la diferencia inexistente entre tabuladores y espacios múltiples. Escribes código, todo parece estar bien alineado. Presiona inicio y falla con un error de espacio porque algunas líneas usan tabulaciones y otras líneas usan espacios.

Afortunadamente, estos errores son fáciles de detectar y tardan solo un par de segundos en corregirse, pero aún así me molestan cada vez. Los problemas disminuyeron cuando cambié a Visual Studio Code, que hace un buen trabajo al evitar la mayoría de los errores de espacios en blanco, pero sigo recibiendo uno o dos al día, especialmente cuando copio cualquier código que usa tabulaciones en lugar de espacios.

Sin embargo, hay otro tipo de errores que ya son mucho más difíciles de encontrar. Cuando tiene una sección de código compleja con muchas capas de bucles anidados y declaraciones if, y realmente no le importa la sangría, es fácil cometer un error. En contraste con las “brechas vs. tab" ya no es un error de sintaxis y no recibirá ningún mensaje. Obviamente, también es posible perder una línea de código en C++, pero para hacerlo, debe moverla fuera de las llaves que encierran el alcance, lo que no sucede con tanta frecuencia por error.

2. Sintaxis

Si bien Python es el único lenguaje líder donde los espacios en blanco son tan importantes, también es el único entre los 5 principales que no usa la sintaxis de llaves estilo C. Desde que C se convirtió en uno de los primeros lenguajes de programación ampliamente utilizados, muchos desarrolladores están acostumbrado a su sintaxis, en relación con la cual fue tomado prestado por una serie de otros idiomas más modernos.

Para mí, la sintaxis de llaves C/C++ se ve y se siente más estructurada que la estructura basada en espacios en blanco de Python. Pero lo más probable es que dependa de cuál fue su primer lenguaje de programación.

Para aquellos que son nuevos en Python, las llaves pueden parecer extrañas y confusas. Si empezaste como programador con C/C++, entonces probablemente encontraste Python mucho más difícil de aprender que otros lenguajes como Java, PHP o JavaScript, que usan una sintaxis similar a C.

Y aunque estoy acostumbrado a la sintaxis de Python, todavía me resulta mucho más difícil cambiar de C++ a Python que, por ejemplo, a PHP.

3. Variables de clase

Aquí hay una pieza muy simple de código C++ que tiene una clase con una variable miembro de matriz de bytes. Creamos dos objetos, y cada uno de ellos asigna un valor único a la matriz de bytes. Luego generamos esos valores y se reflejan como se esperaba.

class TestClass
{
public:
    bytearray data = bytearray(1);
};

TestClass a = TestClass();
a.data[0] = 1;
TestClass b = TestClass();
b.data[0] = 2;
std::cout << (int)a.data[0] << std::endl;
std::cout << (int)b.data[0] << std::endl;

// Conclusion:
// 1
// 2

Y aquí está la misma pieza de código en Python:

class TestClass:
    data = bytearray(1)

a = TestClass()
a.data[0] = 1
b = TestClass()
b.data[0] = 2
print( a.data[0] )
print( b.data[0] )
print( TestClass.data[0] )

# Conclusion:
# 2
# 2
# 2

Parece casi idéntico, excepto por algunas diferencias sintácticas entre C++ y Python. Sin embargo, al generar, todos los valores de la matriz de bytes resultan ser los mismos, lo cual es bastante extraño e inesperado.

Tenía un código muy similar en un proyecto reciente de Python, y como se parecía mucho a lo que estaba acostumbrado en C++, no lo pensé dos veces. Sin embargo, mi programa no funcionó y me llevó mucho tiempo resolver el problema. Cuando declara una variable en una clase en Python, se convierte en la variable de clase por defecto, al igual que las variables estáticas en C++.

Sin embargo, hay otras trampas en este proceso. Echa un vistazo aquí:

class IntTestClass:
    number = 0

a = IntTestClass()
a.number = 1
b = IntTestClass()
b.number = 2
print( a.number )
print( b.number )
print( IntTestClass.number )

# Conclusion:
# 1 
# 2
# 0

Si una variable numérica fuera realmente como una variable estática de C++, existiría solo una vez y siempre tendría el mismo valor. Sin embargo, cuando lo cambiamos en dos objetos, la salida es diferente. Resulta que en Python, cuando cambia el valor de una variable de clase a través de una referencia de objeto, en su lugar se crea una nueva variable para cada instancia, y debe acceder a ella a través del nombre de clase para obtener el valor real de la variable de clase.

Sin embargo, en el ejemplo de matriz de bytes, este no fue el caso y no se creó ninguna variable de instancia nueva, lo cual es completamente confuso. Supongo que tiene que ver con los punteros y las referencias que funcionan detrás de escena, pero este comportamiento de Python no me queda claro, por lo que me mantendré alejado de las variables de clase de ahora en adelante.

4. Falta de transparencia de punteros y enlaces

Además del punto anterior, está la falta de transparencia en Python cuando se trata de referencias y punteros. Algunos valores se pasan por referencia, pero con solo mirar el código, no puede averiguar cuáles. A muchos desarrolladores no les gustan los punteros y las referencias en C++, y si este es su primer idioma, estoy de acuerdo en que agregan complejidad. Sin embargo, una vez que tiene una comprensión básica de cómo funcionan, comienzan a aportar claridad al código, haciendo que todo lo que sucede sea obvio.

5. Miembros de clase privada

Python también carece de la capacidad de controlar el acceso a las funciones y variables de clase: todo está siempre abierto. No es gran cosa, pero sigo prefiriendo usar funciones y variables privadas para una mejor encapsulación y control de acceso. Esto hace que el código sea mucho más limpio y seguro.

6. self vs. this

Otra pequeña diferencia a la que hay que acostumbrarse al migrar de Python a C++ es el uso selfde thisSelf se refieren a la instancia del objeto actual, pero por alguna razón poco clara, Python es el único lenguaje líder que usa, this, para este propósito.  Además, debe pasar la referencia a las funciones de Python de forma explícita, mientras que siempre está disponible implícitamente en C++. this self self this

7. Devolver valores múltiples

Las funciones de Python pueden devolver múltiples valores, lo que inicialmente me pareció muy extraño. Aunque en realidad todavía no se trata de múltiples valores de retorno, porque internamente la función devuelve una tupla sin paréntesis. En C++, devolver múltiples valores ya es más peligroso, así que una vez que te acostumbres a Python, seguramente será una excelente manera de escribir código más legible. 

8. Falta de escritura fuerte

A diferencia de C++, Python no usa tipos de datos estrictos, lo que significa que no tiene que declarar el tipo de una variable cuando la crea. En Python esto sería fácil number = 5, pero en C++ necesitaría especificar un tipo como intfloat, por ejemplo int number = 5;.

Prefiero los lenguajes fuertemente tipados porque facilitan evitar ciertos tipos de errores. Pero al mismo tiempo, también me gustan muchos representantes débilmente tipeados como PHP o JavaScript. Sin embargo, esto también debe tenerse en cuenta para Python. En uno de mis últimos programas que necesitaba enviar datos binarios a través de la red, la diferencia entre los tipos de datos implícitos de Python y los tipos de datos estrictos de C++ fue un obstáculo (por ejemplo, todos los flotantes en Python en C++ son equivalentes double, no float).

9. Falta de constantes

Python no tiene una forma integrada de declarar constantes, lo que puede ser un poco molesto. Al usar la convención de nombrar constantes en letras mayúsculas, puede decirles a otros que una variable debe ser constante, pero eso no impide que nadie la reasigne. Al mismo tiempo, en C ++, declarar variables mientras constfunciona es mucho más interesante, lo que hace que el código sea más limpio y seguro.

Cambiar entre diferentes lenguajes de programación siempre toma tiempo para acostumbrarse, ya que algunas diferencias están inevitablemente presentes. Sin embargo, Python hace muchas cosas de manera muy diferente, lo que hace que sea especialmente difícil migrar desde un lenguaje como C++.

Una cosa es cuando conoces todas las funciones de Python, pero si lo usas solo de vez en cuando, puede que te sorprenda un nuevo detalle que no conocías antes. Para mí, en este caso, las variables de clase estáticas implícitas se convirtieron en una gran sorpresa.

Pero a pesar de todo esto, mi último proyecto de Python resultó ser muy bueno, y planeo usar este lenguaje más a menudo, porque para algunas tareas resulta muy conveniente.



Report Page