• Inicio
  • Blog
  • Wargames
  • Buscar
  • Ingresar
  • Registrarse

    • Hack x Crack - Comunidad de Seguridad informática »
    • Programación »
    • Scripting »
    • Python »
    • Clases dentro de clases [Consulta]
    El evento Bitup2019 necesita tu ayuda! Click aquí para saber más
    • Imprimir
    Páginas: [1]   Ir Abajo

    Autor Tema: Clases dentro de clases [Consulta]  (Leído 2441 veces)

    Desconectado URSS_Lover

    • { L0 } Ñuub
    • Mensajes: 34
      • Ver Perfil
    Clases dentro de clases [Consulta]
    « en: Agosto 20, 2017, 01:48:21 am »
    Hola colegas, hoy he estado trasteando con python intentando hacer un programita que no viene al cuento, pero se me ocurrió una solución que me ha desolucionado todo, jajaja, quiero hacer en el programa una clase "entidad", la "entidad" tiene "nombre" y una "posición" en el espacio, pero por comodidad, quería hacer que la "posición" fuera otro objeto, con los atributos "x" y "y", ¿Es posible hacer eso? Basicamente una de las tantas cosas que intenté fué declarar una clase dentro de otra clase, que al llamar la clase mas alta esta llamara a la clase mas baja, pero osea, me lo ejecutó, mas al intentar acceder al clase1.clase2.atributo no me lo reconoce (aunque ojo, si me deja acceder así a la clase2).
    « Última modificación: Agosto 20, 2017, 02:05:47 am por URSS_Lover »
    En línea

    Desconectado ravenheart

    • { L7 } Juanker
    • *******
    • Mensajes: 1360
    • Todos mis mensajes están bajo la licencia WTFPL v2
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #1 en: Agosto 20, 2017, 09:04:22 am »
    ¿Cómo lo has hecho? Tendría que funcionar.
    En línea
    You do not need hope if you have drama to back you up.

    Desconectado URSS_Lover

    • { L0 } Ñuub
    • Mensajes: 34
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #2 en: Agosto 20, 2017, 06:47:12 pm »
    Código: Python
    1. class entidad:
    2.         class pos:
    3.                 def __init__(self,x,y):
    4.                         self.x = x
    5.                         self.y = y
    6.                 def mov(self,dim,direccion,i):
    7.                         if (dim == 0) & (direccion == 0): self.x += i
    8.                         elif (dim == 0) & (direccion == 1): self.x -= i
    9.                         elif (dim == 1) & (direccion == 0): self.y += i
    10.                         elif (dim == 1) & (direccion == 1): self.y -= i
    11.                         else: print "Error"
    12.         def __init__(self,identidad,x,y):
    13.                 self.identidad = identidad
    14.                 self.pos(x,y)
    15.         def mov(self,dim,direccion,i):
    16.                 self.pos.mov(dim,direccion,i)

    Pero al momento de instanciar un elemento de la clase entidad e intentar acceder a su posición:

    Citar
    >>> import Cementerio
    >>> Kase_o = Cementerio.entidad("Kase",0,0)
    >>> Kase_o.pos
    <class Cementerio.pos at 0xb729450c>
    >>> Kase_o.pos.x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class pos has no attribute 'x'
    >>> Kase_o.pos.y
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class pos has no attribute 'y'
    >>>

    Cementerio es el archivo en el que tengo la clase, el nombre es simplemente porque allí va todo el codigo disfuncional para hacerle autopsia luego y poder ver qué fue lo que hice mal, jajaja.
    En línea

    Desconectado Zarkrosh_7

    • { L1 } Newbie
    • *
    • Mensajes: 53
    • La única iglesia que ilumina es la que arde
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #3 en: Agosto 20, 2017, 07:48:46 pm »
    Tienes que declarar las clases por separado.

    Código: Python
    1. class Motor:
    2.     def __init__(self, potencia):
    3.         self.potencia = potencia
    4.  
    5. class Coche:
    6.     def __init__(self, marca):
    7.         self.marca = marca
    8.         self.motor = Motor(200)
    9.  
    10. coche = Coche("Ford")
    11. print "Marca:", coche.marca
    12. print "Potencia:", coche.motor.potencia
    En línea

    Desconectado URSS_Lover

    • { L0 } Ñuub
    • Mensajes: 34
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #4 en: Agosto 20, 2017, 08:34:12 pm »
    Lo había contemplado como posibilidad, ¿pero entonces lo que intento hacer no es válido? Me ha parecido interesante que a un colega en la universidad le han pedido hacer el tipico programa de gestión de notas a los estudiantes de un aula, me ha parecido que lo mas facil era hacer lo de la clase "aula" y la clase "estudiantes" dentro de la clase "aula", pero bueno... Supongo que no tengo otra opción.
    Instanciar una clase como miembro de otra clase... Al final tiene sentido... Bueno, gracias bro. Usaré esa practica.
    En línea

    Desconectado deni_celine

    • { L1 } Newbie
    • *
    • Mensajes: 66
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #5 en: Agosto 21, 2017, 03:33:59 am »
    Si te fijas cuando consultas Kase0.pos te dice que es una clase, no una instancia , independiente si  colocas las dos clases juntas o por separado, lo que tienes que hacer es crear una instancia de la segunda clase.

    Ejemplo , podrías tener un attr posición , que instancie una "pos"
    Código: [Seleccionar]
    self.posicion = self.pos(x,y)
    O podrías sobrescribir el attr pos
    Código: [Seleccionar]
    self.pos = self.pos(x,y)
    En línea

    Desconectado URSS_Lover

    • { L0 } Ñuub
    • Mensajes: 34
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #6 en: Agosto 21, 2017, 04:38:18 am »
    Gracias Deni, he probado lo que me has dicho de instanciar la clase (realmente si me faltó) y sigue sin funcionar:
    Citar
    Python 2.7.9 (default, Aug 13 2016, 16:41:35)
    [GCC 4.9.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> class auto:
    ...     class motor:
    ...             def __init__(self,potencia):
    ...                     self.potencia = potencia
    ...     def __init__(self,potencia,marca):
    ...             self.marca = marca
    ...             self.potencia = self.motor(potencia)
    ...
    >>> auto
    <class __main__.auto at 0xb72e047c>
    >>> auto.motor
    <class __main__.motor at 0xb72e041c>
    >>> iFord = auto(100,"Ford")
    >>> iFord.marca
    'Ford'
    >>> iFord.motor.potencia
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class motor has no attribute 'potencia'
    >>> iFord.motor
    <class __main__.motor at 0xb72e041c>
    >>> iFord.motor(200)
    <__main__.motor instance at 0xb72e7d8c>
    >>> iFord = iFord.motor(200)
    >>> iFord.motor.potencia
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: motor instance has no attribute 'motor'
    >>> auto.motor.potencia
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class motor has no attribute 'potencia'
    >>>
    Nada, pero bueno, a menos lo que ha dicho Zarkrosh me ha servido, es la unica forma que he tenido de ejecutar mi programa.
    En línea

    Desconectado ravenheart

    • { L7 } Juanker
    • *******
    • Mensajes: 1360
    • Todos mis mensajes están bajo la licencia WTFPL v2
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #7 en: Agosto 21, 2017, 05:48:02 pm »
    Citar
    >>> iFord.motor.potencia
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class motor has no attribute 'potencia'

    Ten en cuenta que a la instancia de motor dentro de auto la has llamad "potencia":
    Código: [Seleccionar]
    class auto:
         def __init__(self,potencia,marca):
                 self.marca = marca
                 ***self.potencia = self.motor(potencia)***

    Tendrías que haber hecho:
    iFord.potencia.potencia


    En cualquier caso, anidar clases no es muy útil salvo para desambiguar (si tuvieras que representar un coche completamente, seguramente necesitarías diferenciar coche.motor de coche.elevalunas.motor, por poner un ejemplo fácil de ver), y para ciertos usos bastante avanzados. Un ejemplo son los iteradores de C++, que se definen en función a tipos parametrizados. Y entonces, no es lo mismo std::vector<int>::iterator que std::vector<std::string>::iterator.


    Está bien saber que existen clases anidadas, pero mejor no usarlas, salvo que tengas un buen motivo y sepas lo que estás haciendo.
    « Última modificación: Agosto 21, 2017, 06:00:12 pm por ravenheart »
    En línea
    You do not need hope if you have drama to back you up.

    Desconectado URSS_Lover

    • { L0 } Ñuub
    • Mensajes: 34
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #8 en: Agosto 22, 2017, 03:40:05 am »
    Cita de: ravenheart en Agosto 21, 2017, 05:48:02 pm
    Citar
    >>> iFord.motor.potencia
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: class motor has no attribute 'potencia'

    Ten en cuenta que a la instancia de motor dentro de auto la has llamad "potencia":
    Código: [Seleccionar]
    class auto:
         def __init__(self,potencia,marca):
                 self.marca = marca
                 ***self.potencia = self.motor(potencia)***

    Tendrías que haber hecho:
    iFord.potencia.potencia


    En cualquier caso, anidar clases no es muy útil salvo para desambiguar (si tuvieras que representar un coche completamente, seguramente necesitarías diferenciar coche.motor de coche.elevalunas.motor, por poner un ejemplo fácil de ver), y para ciertos usos bastante avanzados. Un ejemplo son los iteradores de C++, que se definen en función a tipos parametrizados. Y entonces, no es lo mismo std::vector<int>::iterator que std::vector<std::string>::iterator.


    Está bien saber que existen clases anidadas, pero mejor no usarlas, salvo que tengas un buen motivo y sepas lo que estás haciendo.

    Pues al final me ha salido:

    Citar
    >>> class auto:
    ...     class motor:
    ...             def __init__(self,potencia):
    ...                     self.potencia = potencia
    ...     def __init__(self,marca,potencia):
    ...             self.marca = marca
    ...             self.imotor = self.motor(potencia)
    ...
    >>> iFord = auto("Ford",200)
    >>> iFord.marca
    'Ford'
    >>> iFord.imotor
    <__main__.motor instance at 0xb731abec>
    >>> iFord.imotor.potencia
    200
    >>>

    Gracias Raven, al final mi error ha sido practicamente el de comerme el punto y coma, en Python. Jajaja. Menudo despiste y lo de anidar clases es mas que todo para experimentar, consideraré lo de no usarlo por norma general.
    Por cierto, datos para el que quiera hacer esto. Como al hacer un "self.motor = self.motor(dato)" estaría sobreescribiendo el motor, simplemente lo que estoy haciendo es usar barras bajas para identificar métodos en las clases y clases anidadas y usar nombres sin barras bajas para los miembros normales de una clase. Y ¡Woalah!
    « Última modificación: Agosto 22, 2017, 04:54:50 am por URSS_Lover »
    En línea

    Desconectado ravenheart

    • { L7 } Juanker
    • *******
    • Mensajes: 1360
    • Todos mis mensajes están bajo la licencia WTFPL v2
      • Ver Perfil
    Re:Clases dentro de clases [Consulta]
    « Respuesta #9 en: Agosto 22, 2017, 11:33:07 pm »
    Cita de: URSS_Lover en Agosto 22, 2017, 03:40:05 am
    Menudo despiste y lo de anidar clases es mas que todo para experimentar, consideraré lo de no usarlo por norma general.
    Tampoco pasa nada si te apetece usarlo, pero no te va a aportar mucho, salvo en los casos que he comentado.
    En línea
    You do not need hope if you have drama to back you up.

    • Imprimir
    Páginas: [1]   Ir Arriba
    • Hack x Crack - Comunidad de Seguridad informática »
    • Programación »
    • Scripting »
    • Python »
    • Clases dentro de clases [Consulta]
     

    • SMF | SMF © 2013, Simple Machines
    • XHTML
    • RSS
    • WAP2
    Va un mudo y le dice a un sordo: Hack x Crack usa cookies. Pues eso... Learn more