A saída está correta para a forma que você chamou, apesar de não ser o resultado esperado.
O que ocorre é que o método __init__ é um construtor e tem uma convenção em sua implementação para ele apenas construir o objeto.
d = Data(21, 11, 2007) cria uma instância da classe Data chamando o construtor e atribui a referência em memória do objeto à variável d.
Quando chama o print(d), ele invoca o método __str__ da classe Data herdado de Object. Como não foi sobrescrito, ele imprime na tela o objeto e suas referencias de classe e memória.
Para imprimir corretamente, faça o construtor apenas construir o objeto e sobrescreva o método __str__ retornando a string desejada.
Criei essa implementação para o problema adaptando a forma como você fez:
Em datas.py
class Data:
def __init__(self, dia: int, mes: int, ano: int):
self.__dia = dia
self.__mes = mes
self.__ano = ano
@property
def dia(self):
return self.__dia
@property
def mes(self):
return self.__mes
@property
def ano(self):
return self.__ano
def formadata(self):
print(f'{self.dia:02d}/{self.mes:02d}/{self.ano}')
def __str__(self):
return f'{self.dia:02d}/{self.mes:02d}/{self.ano}'
Em main.py
from datas import Data
if __name__ == "__main__":
d = Data(21, 11, 2007)
d.formadata()
print(d)
Tanto d.formadata() quanto print(d) imprimem na tela o resultado esperado.