Pular para o conteúdo principal

Classes internas em Python

Neste tutorial básico de Python, você vai aprender por que e quando usar classes internas.
· 5 min leer

Explore com IA

Você provavelmente já ouviu falar de funções aninhadas em Python. Se você sabe o que isso significa, entender classes internas/aninhadas vai ser tranquilo. Aqui vamos explorar alguns pontos sobre classes internas ou aninhadas.

1. Classes internas ou aninhadas

Uma classe interna ou aninhada é definida dentro de outra classe. Veja a estrutura de classes internas ou aninhadas.

## classe externa
class Outer:

    ## classe interna
    class Inner:
        pass

        ## classe interna em múltiplos níveis
        class InnerInner:
            pass

    ## outra classe interna
    class _Inner:
        pass

    ## ...

    pass

Execute e edite o código deste tutorial online

Executar código

2. Por que usar classes internas?

  1. Agrupar duas ou mais classes. Suponha que você tenha as classes Car e Engine. Todo Car precisa de um Engine. Mas o Engine não será usado sem um Car. Então, você transforma Engine em uma classe interna de Car. Isso ajuda a organizar e economizar código.

  2. Ocultar código é outro uso de classes aninhadas. Você pode esconder as classes aninhadas do mundo externo.

  3. Facilita o entendimento do código. As classes estão intimamente relacionadas aqui. Você não precisa procurar por elas no projeto — estão todas juntas.

Classes internas ou aninhadas não são o recurso mais comum em Python, mas podem ser muito úteis. O código fica mais simples de organizar quando você usa classes internas ou aninhadas.

3. Codificando classes internas

Implementar classes internas ou aninhadas não é difícil. Você pode ver a estrutura do código aqui.

Você acessa a classe interna dentro da classe externa usando a palavra-chave self. Assim, dá para criar rapidamente uma instância da classe interna e operar a partir da classe externa como preferir. Já o contrário não funciona: você não consegue acessar a classe externa diretamente a partir de uma classe interna. Veja o exemplo abaixo.

class Outer:
    """Outer Class"""

    def __init__(self):
        ## instanciando a classe 'Inner'
        self.inner = self.Inner()

    def reveal(self):
        ## chamando a função display da classe 'Inner'
        self.inner.inner_display("Chamando a função da classe Inner a partir da classe Outer")

    class Inner:
        """Inner Class"""

        def inner_display(self, msg):
            print(msg)

Agora, vamos criar a instância da classe Outer e chamar seu método reveal() para executar o método inner_display() da classe Inner.

## criando uma instância da classe 'Outer'
outer = Outer()
## chamando o método 'reveal()'
outer.reveal()
Chamando a função da classe Inner a partir da classe Outer

Veja outra forma de acessar a classe interna. Esse jeito é um pouco menos eficiente.

Outer().Inner().inner_display("Chamando o método da classe Inner diretamente")
Chamando o método da classe Inner diretamente

E se você quiser criar uma instância da classe interna fora da classe externa? Dá para fazer? Sim! Veja como instanciar a classe interna fora da classe externa.

outer = Outer()

## instanciando a classe interna
inner = outer.Inner() ## inner = Outer().Inner() ou inner = outer.inner
inner.inner_display("Só imprimir!")
Só imprimir!

3.1. Múltiplas classes internas

É uma classe que contém mais de uma classe interna. Você pode ter várias classes internas dentro de uma classe. Como vimos, é fácil implementar múltiplas classes internas.

class Outer:
    """Outer Class"""

    def __init__(self):
        ## instanciando a classe 'Inner'
        self.inner = self.Inner()
        ## instanciando a classe '_Inner'
        self._inner = self._Inner()

    def show_classes(self):
        print("This is Outer class")
        print(inner)
        print(_inner)

    class Inner:
        """First Inner Class"""

        def inner_display(self, msg):
            print("This is Inner class")
            print(msg)

    class _Inner:
        """Second Inner Class"""

        def inner_display(self, msg):
            print("This is _Inner class")
            print(msg)

    ## ...

O acesso às classes é o mesmo que vimos antes. Veja o exemplo para entender melhor.

## instanciando as classes

## classe 'Outer'
outer = Outer()
## classe 'Inner'
inner = outer.Inner() ## inner = outer.inner ou inner = Outer().Inner()
## classe '_Inner'
_inner = outer._Inner() ## _inner = outer._outer ou _inner = Outer()._Inner()

## chamando os métodos
outer.show_classes()

print()

## classe 'Inner'
inner.inner_display("Só imprimir!")

print()

## classe '_Inner'
_inner.inner_display("Só mostrar!")
This is Outer class
<__main__.Outer.Inner object at 0x0000021B37962048>
<__main__.Outer._Inner object at 0x0000021B37962160>

This is Inner class
Só imprimir!

This is _Inner class
Só mostrar!

3.2. Classes internas em múltiplos níveis

Em classes internas em múltiplos níveis, a classe interna contém outra classe, que é interna em relação à anterior. Você pode ver a estrutura dessa hierarquia aqui:

class Outer:
    """Outer Class"""

    def __init__(self):
        ## instanciando a classe 'Inner'
        self.inner = self.Inner()
        ## instanciando a classe multinível 'InnerInner'
        self.innerinner = self.inner.InnerInner()

    def show_classes(self):
        print("This is Outer class")
        print(inner)

    ## classe interna
    class Inner:
        """First Inner Class"""

        def __init__(self):
            ## instanciando a classe 'InnerInner'
            self.innerinner = self.InnerInner()

        def show_classes(self):
            print("This is Inner class")
            print(self.innerinner)

        ## classe interna em múltiplos níveis
        class InnerInner:

            def inner_display(self, msg):
                print("This is multilevel InnerInner class")
                print(msg)

        def inner_display(self, msg):
            print("This is Inner class")
            print(msg)

    ## ...

Veja como instanciar a classe interna em múltiplos níveis.

outer = Outer()

inner = outer.Inner()

## esta é a instância da classe 'InnerInner'
innerinner = inner.InnerInner() ## innerinner = Outer().Inner().InnerInner()

## vamos chamar seu método inner_display
innerinner.inner_display("Só imprimir!")
This is multilevel InnerInner class
Só imprimir!

Conclusão

Espero que agora você tenha entendido o conceito de classes internas. É hora de experimentar com classes aninhadas. Bom código! :)

Se quiser aprender mais sobre classes, confira o tutorial de Programação Orientada a Objetos (OOP) em Python da DataCamp.

faça o curso Object-Oriented Programming in Python da DataCamp.

Temas

Relacionado

Tutorial

Tutorial de Python