Anuncios

Bienvenidos sean a este post, hoy veremos como establecer los niveles de acceso para nuestras variables y funciones.

Anuncios

En muchos lenguajes de OOP tales como Java, C# o C++ tenemos la posibilidad de poder restringir el acceso a las variables y metodos de nuestro codigo, en general cada uno tiene su forma de hacerlo pero en general consta de dos tipos basicos:

  • Acceso publico, permite que el elemento sea accedido por todo el codigo
  • Acceso privado, donde solo podra ser accedido dentro del rango que tienen permitido
Anuncios

En python no existe tal cosa pero si un mecanismo por convencion llamado manejo de nombres, la convencion es la siguiente:

Si un elemento no comienza con un guion bajo, se lo considera como publico y puede ser accedido y modificado libremente, de lo contrario cuando comuenza con un guion bajo se considera privado, por lo tanto se usara internamente y no deberia ser accedido o modificado externamente.

El Tinchicus
Anuncios

Un uso muy comun de esto es para metodos que ayuden a otros metodos que seran accedidos publicamente y datos internos, tales como factores de escaleo, o cualquier otro dato que deba guardarse en una constante pero python no crea constantes, tal como sucede con Javascript donde todas estas formas de trabajo son mas convenciones que quedan bajo nuestro criterio.

Anuncios

Si bien el uso de modificadores de acceso nos permite crear posibles errores en nuestro codigo, veamos el siguiente ejemplo para entender este concepto:

>>> class A:
...     def __init__(self, factor):
...             self._factor = factor
...     def op1(self):
...             print('op1 con factor {}'.format(self._factor))
... 
>>> class B(A):
...     def op2(self, factor):
...             self._factor = factor
...             print('op2 con factor {}'.format(self._factor))
... 
>>>
Anuncios

En este caso tenemos dos clases, la primera clase llamada A inicia una variable llamada _factor y despues tenemos un metodo para el mostrar el valor de _factor en op1, la segunda clase llamada B solo tiene un metodo llamado op2 que recibe un valor y lo usamos para establecer un valor a _factor y luego mostraremos el valor del mismo pero en esta funcion, vamos a probarlo:

>>> obj = B(100)
>>> obj.op1()
op1 con factor 100
>>> obj.op2(42)
op2 con factor 42
>>> obj.op1()
op1 con factor 42
>>>
Anuncios

Primero creamos una instancia de B llamada obj y lo hacemos con el valor de 100, lo primero que haremos es mostrar el valor de _factor en op1 y vemos que es el valor que pasamos, luego por medio de op2 establecemos un valor para _factor, usamos la funcion op2 y vemos que se cambio el valor pero si volvemos a usar op1 vemos que se modifico con el ultimo valor, esto es una condicion que no queremos porque este valor se supone que debe quedar fijo y solo se debe modificar por medio de esta funcion y puede generarnos un error o una conducta no deseada, vamos a trabajar sobre este error pero deberemos modificar las clases de la siguiente manera:

>>> class A:
...     def __init__(self, factor):
...             self.__factor = factor
...     def op1(self):
...             print('op1 con factor {}'.format(self.__factor))
... 
>>> class B(A):
...     def op2(self, factor):
...             self.__factor = factor
...             print('op2 con factor {}'.format(self.__factor))
... 
>>>
Anuncios

Si observan solamente agregamos un guion bajo mas a _factor, el resto del codigo sigue siendo el mismo, vamos a probar para ver si funciona:

>>> obj = B(100)
>>> obj.op1()
op1 con factor 100
>>> obj.op2(42)
op2 con factor 42
>>> obj.op1()
op1 con factor 100
>>>
Anuncios

Como podemos ver ahora funciono como queriamos y esto es gracias al mecanismo que describimos anteriormente, dado que si nosotros tenemos una variable con el nombre _factor y le agregamos un guion mas este se convertira automaticamente en _NombreClase__factor, por ejemplo _A__factor, si ejecutaramos el primer codigo de las clases A y B y creamos el objeto nuevamente, al ejecutar el siguiente codigo veremos esta salida:

>>> print(obj.__dict__.keys())
dict_keys(['_factor'])
>>>
Anuncios

Esta nos devolverea todas las claves que se crearon dentro de nuestro objeto y en este caso vemos como _factor es unico y por lo tanto cuando modifiquemos uno se modificaran todos, vamos a ver que sucede con nuestro segundo codigo:

>>> print(obj.__dict__.keys())
dict_keys(['_A__factor', '_B__factor'])
>>>
Anuncios

Como pueden ver ahora tenemos un factor para cada clase y solamente agregando un nuevo guion bajo delante del elemento que deseamos convertirlo en «privado», aunque si bien podemos seguir modificando a este sabemos que solo pertenece a esa clase y no afecta a los elementos con el mismo nombre en las otras clases, no es la restriccion que podemos tener en otros lenguajes pero nos permitira tener elementos independientes en cada clase.

Anuncios

En resumen, hoy hemos visto que es el manejo de nombres, como esto nos permite crear elementos «privados» en nuestra clase, hablamos de como una simple convención nos permite establecer como una variable o nombre se transforma en miembro unica de su clase y dejando de ser publica, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50