Reputation: 41
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
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
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