Reymi Chacon Soto
Reymi Chacon Soto

Reputation: 41

Clock program inheritance help - Python

I am using classes and inheritance to make a clock on Python. I am trying to make a function advance() inside class Fecha which inherits Calendar and Clock. I try to call the attribute self.__hora, but I get "Attribute error: Fecha object has no attribute...". I will post only a part of the code because it is a little big:

class Reloj(object):

    __segundo = Contador(0, 60)
    __minuto = Contador(0, 60)
    __hora = Contador(0, 24)

    def __init__(self, s, minu, h):

        self.__segundo.setCuenta(s)
        self.__minuto.setCuenta(minu)
        self.__hora.setCuenta(h)


    def set(self, s, minu, h):

        self.__segundo.setCuenta(s)
        self.__minuto.setCuenta(minu)
        self.__hora.setCuenta(h)

    def tic(self):

        self.__segundo.contar()

Class Reloj is a little bigger, but the rest are just display functions. This is the class Fecha:

class Fecha(Reloj, Calendario):

def __init__(self,d,m,a,s,minu,h):

    Reloj.__init__(self,s,minu,h)
    Calendario.__init__(self,d,m,a)

def avanzar(self):

    hora_previa= self.__hora
    Reloj.tic(self)
    if self.__hora < hora_previa:
        self.avanzar()

def __str__(self):

     return Calendario.__str__(self) +","+ Reloj.__str__(self)

Upvotes: 1

Views: 175

Answers (3)

Blckknght
Blckknght

Reputation: 104722

Your AttributeError has to do with the attribute names you're using. When you prefix an attribute name with two underscores, that invokes Python's name mangling system. It transforms the name from __Foo to _SomeClass__Foo (if the code is in the SomeClass class). It's intended to help you write mixin and proxy classes without worrying about unintentional name conflicts.

You should not use that feature unless you actually need it. Rename your attributes to use just a single underscore if they're intended to be private. Or just give them public names and don't bother trying to hide the implementation details.

You didn't show the code for the Contador type that you're using. If it's not a fancy descriptor or something, you're probably using it wrong when you assign instance of it to class variables in Reloj. You probably want the attributes to be instance variables instead. I'd suggest doing something like:

class Reloj(object):

    def __init__(self, s, minu, h):

        self._segundo = Contador(0, 60)
        self._minuto = Contador(0, 60)
        self._hora = Contador(0, 24)
        self.set(s, minu, h)

    ...

By calling set, we can avoid duplicating its code in __init__, which just needs to set up the attributes properly. The previous code probably shared the time values between every Reloj instance.

Upvotes: 1

Max
Max

Reputation: 315

self.__hora is "privat". Try this self._Relog__hora.

Upvotes: 1

Kenny Chau
Kenny Chau

Reputation: 96

Don't use __ before your variables, instead of:

__segundo = Contador(0, 60)
__minuto = Contador(0, 60)
__hora = Contador(0, 24)

You could use this:

_segundo = Contador(0, 60)
_minuto = Contador(0, 60)
_hora = Contador(0, 24)

Upvotes: 1

Related Questions