class Pessoa:
    # atributo default ou atributo de classe
    olhos = 2

    def __init__(self, *filhos, nome=None, idade=35):
        self.idade = idade
        self.nome = nome
        self.filhos = list(filhos)

    def cumprimentar(self):
        return f'Olá, meu nome é {self.nome}'

    @staticmethod
    def metodo_estatico():
        return 42

    @classmethod
    def nome_e_atributos_de_classe(cls):
        return f'{cls} - olhos {cls.olhos}'


class Homem(Pessoa):
    def cumprimentar(self):
        cumprimentar_da_classe = super().cumprimentar()
        return f'{cumprimentar_da_classe}. Aperto de mão'


class Mutante(Pessoa):
    olhos = 3


if __name__ == '__main__':
    renzo = Mutante(nome='Renzo')
    luciano = Homem(renzo, nome='Luciano')
    print(Pessoa.cumprimentar(luciano))
    print(id(luciano))
    print(luciano.cumprimentar())
    print(luciano.nome)
    print(luciano.idade)
    for filho in luciano.filhos:
        print(filho.nome)
    # criano do atributo dinâmico, vai aparecer apenas para o objeto luciano
    luciano.sobrenome = 'Ramalho'
    # removendo atributo dinamicamente, vai ser removido apenas do objeto luciano
    del luciano.filhos
    # mudano o valor do atributo olhos apenas para luciano
    luciano.olhos = 1
    # apagando o atributo olhos apenas para luciano, mas permanece na classe
    del luciano.olhos
    # verificando quais os atributos existem para cada um
    print(luciano.__dict__)
    print(renzo.__dict__)
    print(Pessoa.olhos)
    print(luciano.olhos)
    print(renzo.olhos)
    print(id(Pessoa.olhos), id(luciano.olhos), id(renzo.olhos))

    print(Pessoa.metodo_estatico(), luciano.metodo_estatico())
    print(Pessoa.nome_e_atributos_de_classe(), luciano.nome_e_atributos_de_classe())

    # Classe Filho herda todos os atributos da Classe Pai
    # Todo Homem (Classe Filho) é uma Pessoa (Classe Pai), mas nem toda Pessoa é um Homem
    pessoa = Pessoa('Anonimo')
    print(isinstance(pessoa, Pessoa))
    print(isinstance(pessoa, Homem))
    print(isinstance(renzo, Pessoa))
    print(isinstance(renzo, Homem))
    print(renzo.olhos)
    print(luciano.cumprimentar())
    print(renzo.cumprimentar())

class Pessoa:
    # atributo default ou atributo de classe
    olhos = 2

    def __init__(self, *filhos, nome=None, idade=35):
        self.idade = idade
        self.nome = nome
        self.filhos = list(filhos)

    def cumprimentar(self):
        return f'Olá, meu nome é {self.nome}'

    @staticmethod
    def metodo_estatico():
        return 42

    @classmethod
    def nome_e_atributos_de_classe(cls):
        return f'{cls} - olhos {cls.olhos}'


class Homem(Pessoa):
    def cumprimentar(self):
        cumprimentar_da_classe = super().cumprimentar()
        return f'{cumprimentar_da_classe}. Aperto de mão'


class Mutante(Pessoa):
    olhos = 3


if __name__ == '__main__':
    renzo = Mutante(nome='Renzo')
    luciano = Homem(renzo, nome='Luciano')
    print(Pessoa.cumprimentar(luciano))
    print(id(luciano))
    print(luciano.cumprimentar())
    print(luciano.nome)
    print(luciano.idade)
    for filho in luciano.filhos:
        print(filho.nome)
    # criano do atributo dinâmico, vai aparecer apenas para o objeto luciano
    luciano.sobrenome = 'Ramalho'
    # removendo atributo dinamicamente, vai ser removido apenas do objeto luciano
    del luciano.filhos
    # mudano o valor do atributo olhos apenas para luciano
    luciano.olhos = 1
    # apagando o atributo olhos apenas para luciano, mas permanece na classe
    del luciano.olhos
    # verificando quais os atributos existem para cada um
    print(luciano.__dict__)
    print(renzo.__dict__)
    print(Pessoa.olhos)
    print(luciano.olhos)
    print(renzo.olhos)
    print(id(Pessoa.olhos), id(luciano.olhos), id(renzo.olhos))

    print(Pessoa.metodo_estatico(), luciano.metodo_estatico())
    print(Pessoa.nome_e_atributos_de_classe(), luciano.nome_e_atributos_de_classe())

    # Classe Filho herda todos os atributos da Classe Pai
    # Todo Homem (Classe Filho) é uma Pessoa (Classe Pai), mas nem toda Pessoa é um Homem
    pessoa = Pessoa('Anonimo')
    print(isinstance(pessoa, Pessoa))
    print(isinstance(pessoa, Homem))
    print(isinstance(renzo, Pessoa))
    print(isinstance(renzo, Homem))
    print(renzo.olhos)
    print(luciano.cumprimentar())
    print(renzo.cumprimentar())

# atributo default ou atributo de classe # criano do atributo dinâmico, vai aparecer apenas para o objeto luciano # removendo atributo dinamicamente, vai ser removido apenas do objeto luciano # mudano o valor do atributo olhos apenas para luciano # apagando o atributo olhos apenas para luciano, mas permanece na classe # verificando quais os atributos existem para cada um # Classe Filho herda todos os atributos da Classe Pai # Todo Homem (Classe Filho) é uma Pessoa (Classe Pai), mas nem toda Pessoa é um Homem