Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Desafio Opcional Aula 03

No final acabei fazendo a solução mais obvia de criar uma classe como todo mundo já tem feito, então nem vou repetir isso aqui.

A respeito desse desafio fiquei com uma dúvida interessante.

Por que antes de criar uma classe do zero tentei antes criar uma classe que filha do datetime.date para isso, assim podendo criar minha classe Data aproveitando todos recursos já disponíveis nessa classe:

from datetime import date


class Data(date):
    def __init__(self, dia, mes, ano):
        super(Data, self).__init__(year=ano, month=mes, day=dia)

    def formatada(self):
        print(self.strftime("%d/%m/%y"))

lindo, mas no momento que tentei instanciar essa classe

data = Data(21, 11, 2007)

tive um problema, pois foi lançado uma exceção informando que o dia não estava dentro do "range" de dias do mês informado.

ValueError: day is out of range for month

Pesquisando um pouco descobri que isso ocorre por que por padrão, quando ocorre uma herança aparentemente no construtor da classe filha assume-se que ele recebe primeiramente os parâmetros do init da classe pai antes de considerar os parâmetros definidos na classe filha. Isto é, como se o init da minha classe Data fosse automaticamente definido como:

def __init__(self, year, month, day, dia, mes, ano):

isto é, quando instanciei anteriormente na verdade estava passando 21 para o year, 11 para month e 2007 para day, o que causou a exceção por que o construtor de date checa se o dia informado é valido para o mês informado e certamente 2007 não é um dia pertencente ao mês de novembro.

Então tentei instanciar a classe da seguinte maneira:

data = Data(dia=21,  mes=11, ano= 2007)

Nesse caso a seguinte exceção foi lançada:

TypeError: Required argument 'year' (pos 1) not found

Conclui que precisaria encontrar uma maneira de sobrescrever o init da classe pai ignorando os parâmetros exigidos para sua construção.

Não encontrei uma maneira de fazer isso. É possível fazer isso no python? Se for, como?

Ps.: Sou desenvolvedor java, então tenho alguns vícios dessa linguagem, e como java permite uma classe ter múltiplos construtores, sinto um pouco de falta disso no python, isso é possível?

1 resposta
solução!

Faaala Lucas, tudo tranquilo?

É possível sim. O seu código não está funcionando porque é necessário sobrescrever o dunder __new__ datetime.date e não o __init__. Algo como:

from datetime import date


class Data(date):

    def __new__(cls, ano, mes, dia):
        return super().__new__(cls, year=ano, month=mes, day=dia)

    def __init__(self, ano, mes, dia):
        super().__init__()  

    def formatada(self):
        return self.strftime("%d/%m/%y")

data = Data(2007, 11, 21)
print(data.formatada())

Quanto ao uso de múltiplos construtores, no python isto é feito por meios de parâmetros padrões, o que quer dizer que ao instanciar uma classe, você pode ou não passar este parâmetro. Por exemplo:

class Pessoa:

    def __init__(self, nome, carro = None):
        self.nome = nome
        self.carro = carro


pessoa_1 = Pessoa('Lucas', True)
pessoa_2 = Pessoa('Nádia')

Neste caso, se não passarmos um valor para o parâmetro carro, ele será None, com isso, podemos instanciar a classe Pessoa com este atributo carro ou sem ele.

Um assunto mais avançado sobre os parâmetros em métodos é sobre os *args e os **kwargs . Deixarei sugestões de leituras sobre isto:

Qualquer dúvida é só falar. Abraços e bons estudos!