Foros del Web » Programando para Internet » Python »

[SOLUCIONADO] Set/Get con properties no funciona, aparecen duplicados o algo raro los campos

Estas en el tema de Set/Get con properties no funciona, aparecen duplicados o algo raro los campos en el foro de Python en Foros del Web. Tengo la siguiente clase y defino sus properties para poder modificar sus atributos de manera segura, pero el código se vuelve loco Código: class Objeto1: ...
  #1 (permalink)  
Antiguo 14/03/2013, 10:08
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Set/Get con properties no funciona, aparecen duplicados o algo raro los campos

Tengo la siguiente clase y defino sus properties para poder modificar sus atributos de manera segura, pero el código se vuelve loco

Código:
class Objeto1:
    def __init__(self, dominios):

        self._dominios = dominios
 
    def __str__(self):
        return "DOMINIOS=>%s" % (self._dominios)
        
    def __get_dominios(self):
        return self._dominios

    def __set_dominios(self, valor):
        self._dominios = valor
        
    dominios = property(fget=__get_dominios, fset=__set_dominios, doc='value of parameter')
En teoria esta clase esta bien definida, pues si hago lo siguiente hay sorpresa....

Cita:
a = Objeto1("192.13.12.11")

a.dominios="Soy un dominio nuevo"

print a._dominios
print a.dominios
Muestra por consola valores distintos!

Código:
192.13.12.11
Soy un dominio nuevo
y si por ejemplo meto el objeto en una lista, el objeto se copia con el valor inicial de dominios, no con el nuevo cambiado.

Por favor alguien entiende cual es el problema?
  #2 (permalink)  
Antiguo 14/03/2013, 22:17
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Lo que pasa es que no estas encapsulando bien la variable.

En python por default todos los atributos de clase son públicos, excepto si la variable empieza con __ (doble guion bajo).

En tu caso tienes una propiedad para dominios y tienes acceso a tu variable de clase.

Código Python:
Ver original
  1. class Objeto1:
  2.     def __init__(self, dominio):
  3.         self.dominio = dominio
  4.  
  5.     def __str__(self):
  6.         return "DOMINIOS => %s" % (self.dominio)
  7.  
  8.     @property
  9.     def dominio(self):
  10.         return self.dominio
  11.  
  12.     @dominio.setter
  13.     def dominio(self, valor):
  14.         self.dominio = valor
  15.  
  16. a = Objeto1("192.13.12.11")
  17.  
  18. a.dominio = "Soy un dominio nuevo"
  19.  
  20. print a
  21. print a.dominio

Supongo que quieres hacer esto.
  #3 (permalink)  
Antiguo 15/03/2013, 03:38
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Muchas gracias es justo lo que estaba buscando.

Respecto a establecer los atributos de tipo privado y poder modificar u obtener su valor mediante los métodos get/set, estaría bien tal cual con este código o habría que añadirles los dos guiones bajos (__) en alguna parte de la declaración?
  #4 (permalink)  
Antiguo 15/03/2013, 12:53
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Código Python:
Ver original
  1. class Objeto1:
  2.     def __init__(self, dominio):
  3.         self.__dominio = dominio
  4.  
  5.     def __str__(self):
  6.         return "DOMINIOS => %s" % (self.__dominio)
  7.  
  8.     @property
  9.     def dominio(self):
  10.         return self.__dominio
  11.  
  12.     @dominio.setter
  13.     def dominio(self, valor):
  14.         self.__dominio = valor
  15.  
  16. a = Objeto1("192.13.12.11")
  17.  
  18. a.dominio = "Soy un dominio nuevo"
  19.  
  20. print a
  21. print a.dominio
  22. print a.__dominio
Lo mismo pero con variables privadas.
  #5 (permalink)  
Antiguo 19/03/2013, 04:36
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

No entiendo esta solucion.... entonces hay dos variables distintas ???? una que se llama dominio y otra que se llama __dominio???

la duda surge porque veo dos print distintos al final
  #6 (permalink)  
Antiguo 19/03/2013, 10:20
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Si al menos corriste el programa te habrás dado cuenta que imprimir __dominio arroja un error, por que es una variable privada.

Entonces lo que estas haciendo estas encapsulando tu variable privada __dominio y la estas exponiendo al mundo por medio de la propiedad dominio.
  #7 (permalink)  
Antiguo 20/03/2013, 03:16
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Muchas gracias, es que es la primera vez que me enfrento al concepto de propiedad para encapsular variables
  #8 (permalink)  
Antiguo 20/03/2013, 03:38
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Cita:
Iniciado por razpeitia Ver Mensaje
Si al menos corriste el programa te habrás dado cuenta que imprimir __dominio arroja un error, por que es una variable privada.

Entonces lo que estas haciendo estas encapsulando tu variable privada __dominio y la estas exponiendo al mundo por medio de la propiedad dominio.
Buenas sigo teniendo problemas, si el elemento a con el valor "Soy un dominio nuevo" lo intento sustituir en el diccionario por el valor antiguo, no se guarda y se mantiene al valor antiguo en esa variable con los __, si ejecuto el mismo codigo quitando los __ se ejecuta correctamente.

Código:
class Sujeto:
    def __init__(self, ip, dominios):
        self.__dominios = dominios
        self.__ip=ip
     
    def __str__(self):
        return "IP=>%s DOMINIOS=> %s" % (self.__ip, self.__dominios)
     
    @property
    def ip(self):
        return self.__ip
     
    @ip.setter
    def ip(self, valor):
        self.__ip = valor

    @property
    def dominios(self):
        return self.__dominios
     
    @dominios.setter
    def dominios(self, valor):
        self.__dominios = valor     
              
      
obj1 = Sujeto("192.13.12.11", "gmal.com:gmail.es:gmail.net")
            
diccionario = {}

diccionario[obj1.ip] = obj1

a = diccionario.get("192.13.12.11")

print a

a.dominios="Soy un dominio nuevo"

diccionario[a.ip] = a

b= diccionario.get("192.13.12.11")

print b
Imprime erroneamente
Cita:
IP=>192.13.12.11 DOMINIOS=> gmal.com:gmail.es:gmail.net
IP=>192.13.12.11 DOMINIOS=> gmal.com:gmail.es:gmail.net
Sin embargo, si hago exactamente el mismo codigo pero quitando los __ funciona como quiero y actualiza correctamente el diccionario

Código:
class Sujeto:
    def __init__(self, ip, dominios):
        self.dominios = dominios
        self.ip=ip
     
    def __str__(self):
        return "IP=>%s DOMINIOS=> %s" % (self.ip, self.dominios)
     
    @property
    def ip(self):
        return self.ip
     
    @ip.setter
    def ip(self, valor):
        self.ip = valor

    @property
    def dominios(self):
        return self.dominios
     
    @dominios.setter
    def dominios(self, valor):
        self.dominios = valor     
              
      
obj1 = Sujeto("192.13.12.11", "gmal.com:gmail.es:gmail.net")
            
diccionario = {}

diccionario[obj1.ip] = obj1

a = diccionario.get("192.13.12.11")

print a

a.dominios="Soy un dominio nuevo"

diccionario[a.ip] = a

b= diccionario.get("192.13.12.11")

print b
Imprime correctamente
Cita:
IP=>192.13.12.11 DOMINIOS=> gmal.com:gmail.es:gmail.net
IP=>192.13.12.11 DOMINIOS=> Soy un dominio nuevo
  #9 (permalink)  
Antiguo 20/03/2013, 04:58
 
Fecha de Ingreso: marzo-2013
Mensajes: 10
Antigüedad: 11 años, 9 meses
Puntos: 0
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Cita:
Iniciado por razpeitia Ver Mensaje
Si al menos corriste el programa te habrás dado cuenta que imprimir __dominio arroja un error, por que es una variable privada.

Entonces lo que estas haciendo estas encapsulando tu variable privada __dominio y la estas exponiendo al mundo por medio de la propiedad dominio.
El print a.__dominios me saltaria error, pero sin embargo si hago:

a.__dominios="Nueva cadena"

No me salta error...no entiendo porque en cada caso hace lo que quiere el interprete :(
  #10 (permalink)  
Antiguo 20/03/2013, 10:13
Avatar de razpeitia
Moderador
 
Fecha de Ingreso: marzo-2005
Ubicación: Monterrey, México
Mensajes: 7.321
Antigüedad: 19 años, 9 meses
Puntos: 1360
Respuesta: Set/Get con properties no funciona, aparecen duplicados o algo raro los ca

Eso fue un error mio.

Debes de heredar de object para poder usar @property de manera correcta.

Código Python:
Ver original
  1. class Sujeto(object):
  2.     def __init__(self, ip, dominios):
  3.         self.__dominios = dominios
  4.         self.__ip=ip
  5.  
  6.     def __str__(self):
  7.         return "IP=>%s DOMINIOS=> %s" % (self.__ip, self.__dominios)
  8.  
  9.     @property
  10.     def ip(self):
  11.         return self.__ip
  12.  
  13.     @ip.setter
  14.     def ip(self, valor):
  15.         self.__ip = valor
  16.  
  17.     @property
  18.     def dominios(self):
  19.         return self.__dominios
  20.  
  21.     @dominios.setter
  22.     def dominios(self, valor):
  23.         self.__dominios = valor
  24.  
  25.  
  26. obj1 = Sujeto("192.13.12.11", "gmal.com:gmail.es:gmail.net")
  27.  
  28. diccionario = {}
  29.  
  30. diccionario[obj1.ip] = obj1
  31.  
  32. a = diccionario.get("192.13.12.11")
  33.  
  34. print a
  35.  
  36. a.dominios="Soy un dominio nuevo"
  37.  
  38. diccionario[a.ip] = a
  39.  
  40. b= diccionario.get("192.13.12.11")
  41.  
  42. print b

En cuanto a lo que mencionas de agregar atributos es una propiedad de cualquier objeto en python (a menos que usen __slots__).

Ejemplo:
Código MySQL:
Ver original
  1. def f(x):
  2.     print x, f.a
  3. f.a = 2
  4. f(10)

Etiquetas: campos, duplicados, lista, properties, raro
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:25.