Curso
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ódigo2. Por que usar classes internas?
-
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.
-
Ocultar código é outro uso de classes aninhadas. Você pode esconder as classes aninhadas do mundo externo.
-
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.