Python Intermediário POO na Prática: o Código e os Comandos que Realmente Contam
Python Intermediário POO: o essencial em um artigo — código real, diagramas e etapas concretas, extratos de um curso de 36 lições.
Sem teoria interminável aqui: abra o terminal e pratique. Aqui está o essencial de Python Intermediário POO, extraído diretamente de um curso completo de 36 lições — com código real que você pode copiar e colar agora.
- Introdução e Instalação
- Revisão de Python
- Funções avançadas e lambdas
- Classes e objetos
- Herança e polimorfismo
Encapsulamento, properties e setters
Objetivos pedagógicos
_x e __x, transformar um atributo em property para adicionar validação e saber quando fazer isso.O que é encapsulamento?
O encapsulamento consiste em ocultar os detalhes internos de uma classe e expor apenas uma interface controlada.
Convenções Python
Python não força a confidencialidade (ao contrário de Java). Ele usa convenções baseadas no nome.
| Convenção | Significado | Efeito real |
|---|---|---|
nom | Público | Acesso livre, faz parte da API |
_nom | Protegido (convenção) | "Não toque, a menos que saiba o que está fazendo" |
__nom | Privado (name mangling) | Renomeado para _NomClasse__nom |
nom_ | Evita colisão com palavra-chave | Ex: class_ em vez de class |
class CompteBancaire:
def __init__(self, titulaire, solde):
self.titulaire = titulaire # public
self._solde = solde # convention : ne pas toucher
self.__pin = "1234" # privé (name mangling)
c = CompteBancaire("Alice", 1000)
print(c.titulaire) # OK
print(c._solde) # accessible mais déconseillé
# print(c.__pin) # AttributeError !
print(c._CompteBancaire__pin) # accessible avec le nom manglé__ não é uma segurança — É um mecanismo para evitar colisões acidentais na herança. Para segurança real, use permissões no nível do sistema.O problema sem encapsulamento
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
t = Temperature(25)
t.celsius = -500 # absurde !
print(t.celsius) # -500Nenhuma validação. O -500 é impossível (zero absoluto = -273.15), mas Python aceita.
@property : transformar um atributo em método
Um @property faz com que uma chamada como obj.attribut execute na verdade um método, sem alterar a sintaxe de uso.
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
@property
def celsius(self):
return self._celsius
@celsius.setter
def celsius(self, valeur):
if valeur < -273.15:
raise ValueError("Sous le zéro absolu, impossible")
self._celsius = valeur
t = Temperature(25)
print(t.celsius) # 25 (appelle le getter)
t.celsius = 30 # appelle le setter, OK
t.celsius = -300 # ValueError !t.celsius (simples), mas adiciona controle invisível. O código do usuário não precisa mudar nada.Property somente leitura
Para um atributo calculado (derivado de outros) que não deve ser modificado diretamente.
class Cercle:
def __init__(self, rayon):
self.rayon = rayon
@property
def diametre(self):
return self.rayon * 2
@property
def aire(self):
from math import pi
return pi * self.rayon ** 2
c = Cercle(5)
print(c.diametre) # 10
print(c.aire) # 78.539...
# c.aire = 100 # AttributeError : pas de setterProperty completa com getter, setter, deleter
class Personne:
def __init__(self, nom):
self._nom = nom
@property
def nom(self):
return self._nom
@nom.setter
def nom(self, valeur):
if not isinstance(valeur, str) or len(valeur) < 2:
raise ValueError("Nom invalide")
self._nom = valeur.title() # normalisation
@nom.deleter
def nom(self):
print("Suppression du nom")
self._nom = None
p = Personne("alice")
print(p.nom) # Alice (normalisé)
p.nom = "bob"
print(p.nom) # Bob
del p.nom # Suppression du nomCaso prático : CompteBancaire com validação
class CompteBancaire:
def __init__(self, titulaire, solde=0):
self.titulaire = titulaire
self._solde = 0
self.solde = solde # passe par le setter !
@property
def solde(self):
return self._solde
@solde.setter
def solde(self, valeur):
if valeur < 0:
raise ValueError("Solde négatif interdit")
self._solde = valeur
def deposer(self, montant):
if montant <= 0:
raise ValueError("Montant doit être positif")
self.solde += montant # passe par le setter
def retirer(self, montant):
if montant > self._solde:
raise ValueError("Solde insuffisant")
self.solde -= montant
c = CompteBancaire("Alice", 1000)
c.deposer(500)
print(c.solde) # 1500
# c.solde = -100 # ValueErrorHerança simples
Objetivos pedagógicos
super().O conceito
A herança permite criar uma classe especializada a partir de uma classe geral. A classe filha recupera tudo o que a classe mãe oferece e depois adiciona ou modifica.
Chien é-um Animal.Primeiro exemplo
class Animal:
def __init__(self, nom, age):
self.nom = nom
self.age = age
def manger(self):
print(f"{self.nom} mange")
def dormir(self):
print(f"{self.nom} dort")
class Chien(Animal):
def aboyer(self):
print(f"{self.nom} : Wouaf !")
rex = Chien("Rex", 5)
rex.manger() # hérité d'Animal
rex.dormir() # hérité d'Animal
rex.aboyer() # propre à Chien
print(rex.age) # héritéChien não define __init__: Python usa automaticamente o de Animal.
Sobrescrever (override) um método
A classe filha pode redefinir um método da mãe para adaptar seu comportamento.
class Animal:
def parler(self):
print("Bruit générique d'animal")
class Chien(Animal):
def parler(self):
print("Wouaf !")
class Chat(Animal):
def parler(self):
print("Miaou")
for a in [Chien(), Chat(), Animal()]:
a.parler()
# Wouaf !
# Miaou
# Bruit générique d'animala.parler() produz um resultado diferente dependendo da classe real de a. É um dos 4 pilares da POO.super() : chamar o método pai
Ao sobrescrever um método, frequentemente queremos completar o comportamento pai em vez de substituí-lo.
class Animal:
def __init__(self, nom, age):
self.nom = nom
self.age = age
def description(self):
return f"{self.nom}, {self.age} ans"
class Chien(Animal):
def __init__(self, nom, age, race):
super().__init__(nom, age) # appelle Animal.__init__
self.race = race
def description(self):
base = super().description() # appelle Animal.description
return f"{base}, race {self.race}"
rex = Chien("Rex", 5, "Labrador")
print(rex.description()) # Rex, 5 ans, race Labrador__init__, você deve chamar super().__init__(...) para inicializar os atributos da mãe. Esquecer = bugs garantidos.Verificar a parentela : isinstance e issubclass
rex = Chien("Rex", 5, "Labrador")
print(isinstance(rex, Chien)) # True
print(isinstance(rex, Animal)) # True (héritage)
print(isinstance(rex, Chat)) # False
print(issubclass(Chien, Animal)) # True
print(issubclass(Animal, Chien)) # Falseisinstance(x, Animal) em vez de type(x) == Animal. A primeira forma respeita a herança.Quando usar herança?
| Relação | Herança? |
|---|---|
| Chien é-um Animal | Sim |
| Roman é-um Livre | Sim |
| Voiture tem-um Moteur | Não — composição |
| Bibliothèque contém Livres | Não — composição |
Caso concreto : aplicação biblioteca
class Livre:
def __init__(self, titre, auteur, isbn):
self.titre = titre
self.auteur = auteur
self.isbn = isbn
self.disponible = True
def description(self):
return f"{self.titre} de {self.auteur}"
class Roman(Livre):
def __init__(self, titre, auteur, isbn, genre):
super().__init__(titre, auteur, isbn)
self.genre = genre
def description(self):
return f"{super().description()} -- roman {self.genre}"
class LivreNumerique(Livre):
def __init__(self, titre, auteur, isbn, format_fichier):
super().__init__(titre, auteur, isbn)
self.format_fichier = format_fichier
def telecharger(self):
print(f"Téléchargement de {self.titre}.{self.format_fichier}")
dune = Roman("Dune", "Herbert", "978...", "science-fiction")
ebook = LivreNumerique("1984", "Orwell", "978...", "epub")
print(dune.description()) # Dune de Herbert -- roman science-fiction
print(ebook.description()) # 1984 de Orwell
ebook.telecharger() # Téléchargement de 1984.epubHierarquias comuns em Python
Lambda, map, filter, reduce
lambda) e as funções de ordem superior (map, filter, reduce), que permitem transformar e filtrar dados de forma muito concisa.Objetivos pedagógicos
lambda e escolher entre map/filter e uma list comprehension conforme o contexto.O que é uma lambda?
Uma lambda é uma função anônima (sem nome) que cabe em uma única linha. É usada para operações curtas passadas como argumento para outra função.
Sintaxe
lambda parametres: expression
Comparação
def doubler(x):
return x * 2
doubler_lambda = lambda x: x * 2
print(doubler(5)) # 10
print(doubler_lambda(5)) # 10def clássico é como criar uma receita nomeada em um livro. Uma lambda é rabiscar uma receita em um post-it e entregá-la imediatamente a alguém.Lambdas com múltiplos parâmetros
somme = lambda a, b: a + b print(somme(3, 4)) # 7 est_pair = lambda n: n % 2 == 0 print(est_pair(8)) # True
return explícito, sem múltiplas linhas. Quando for mais complexo, use def.map() : transformar cada elemento
map(fonction, iterable) aplica a função a cada elemento e retorna um iterador. Frequentemente envolve-se em list().
prix = [10, 25, 7, 50] prix_ttc = list(map(lambda p: p * 1.20, prix)) print(prix_ttc) # [12.0, 30.0, 8.4, 60.0] mots = ["python", "poo", "code"] majuscules = list(map(str.upper, mots)) print(majuscules) # ['PYTHON', 'POO', 'CODE']
Com várias sequências
a = [1, 2, 3] b = [10, 20, 30] sommes = list(map(lambda x, y: x + y, a, b)) print(sommes) # [11, 22, 33]
filter() : manter o que passa no teste
notes = [12, 8, 15, 6, 18, 11] reussites = list(filter(lambda n: n >= 10, notes)) print(reussites) # [12, 15, 18, 11] mots = ["chat", "chien", "ours", "lion"] courts = list(filter(lambda m: len(m) <= 4, mots)) print(courts) # ['chat', 'ours', 'lion']
Este artigo cobre os trechos mais úteis — o curso completo Python Intermediário POO (11 capítulos, 36 lições, exercícios corrigidos e projeto final) leva você até o fim.
./acceder-au-cours-complet curso gratuito : Dominando Claude CodeFAQ
Quanto tempo para aprender Python Intermediário POO?
É preciso pré-requisitos?
Por onde começar concretamente?
📬 Quer receber este tipo de guia toda semana? Inscreva-se gratuitamente — código real, zero enrolação.