Classes e Objetos em Python
O Python possui vários tipos embutidos, como int
, str
, entre outros, que podemos usar em um programa. Além disso, permite a criação de tipos personalizados usando classes. Uma classe representa uma entidade, e um objeto é a concretização específica dessa classe.
Podemos usar uma analogia para entender o conceito. Todos nós temos uma ideia de uma pessoa, que possui nome, idade e outras características, e que pode realizar ações, como caminhar, correr e pensar. Esse conjunto de características e ações representa um "molde" que podemos chamar de classe. A concretização desse molde varia entre as pessoas: cada uma tem um nome e características próprios. Cada pessoa específica representaria um objeto dessa classe.
Em Python, uma classe é definida com a palavra-chave class
:
class NomeDaClasse:
atributos_da_classe
métodos_da_classe
Dentro da classe, definimos seus atributos (características) e métodos (funções). A seguir, um exemplo básico:
class Person:
pass
Aqui, a classe Person
representa uma pessoa de maneira abstrata, sem definir métodos ou atributos específicos. Usamos a instrução pass
para representar a ausência de conteúdo, exigida pela sintaxe do Python. Com isso, criamos uma estrutura de classe vazia.
Uma vez que a classe foi definida, podemos criar objetos dela:
class Person:
pass
tom = Person() # criação do objeto tom
bob = Person() # criação do objeto bob
No exemplo acima, tom
e bob
são objetos da classe Person
. Para criar um objeto, usamos uma função especial chamada construtor, que recebe o nome da classe e retorna um objeto dela. Neste caso, Person()
chama o construtor que, por padrão, não possui parâmetros.
Construtores
O construtor é responsável pela criação dos objetos da classe. No exemplo anterior, usamos o construtor padrão sem parâmetros, disponível para todas as classes. Porém, podemos definir explicitamente um construtor na classe usando o método especial __init__()
.
class Person:
def __init__(self):
print("Criando um objeto Person")
tom = Person() # Exibe: "Criando um objeto Person"
No código acima, definimos um construtor para a classe Person
. Esse método especial deve aceitar pelo menos um parâmetro, self
, que faz referência ao objeto atual. Construtores geralmente são usados para realizar ações específicas no momento da criação do objeto.
Ao criar um objeto:
tom = Person()
o construtor __init__()
é chamado, exibindo a mensagem “Criando um objeto Person” no console. Vale lembrar que o construtor se comporta como uma função comum, mas é chamado com o nome da classe em vez de __init__
, e o Python gerencia automaticamente o parâmetro self
.
Atributos de Objeto
Os atributos guardam o estado do objeto e podem ser definidos e configurados usando a palavra-chave self
. Veja o exemplo:
Atributos de Objeto
Os atributos guardam o estado do objeto e podem ser definidos e configurados usando a palavra-chave self
. Veja o exemplo:
class Person:
def __init__(self, name, age):
self.name = name # nome da pessoa
self.age = age # idade da pessoa
tom = Person("Tom", 22)
# acessando atributos
print(tom.name) # Saída: Tom
print(tom.age) # Saída: 22
# modificando atributos
tom.age = 37
print(tom.age) # Saída: 37
Aqui, o construtor da classe Person agora recebe name
e age
como parâmetros, armazenando-os como atributos. No construtor, self.name
recebe o valor de name
, e self.age
, o de age
. O nome dos atributos não precisa necessariamente corresponder ao dos parâmetros.
Quando chamamos o construtor com argumentos:
tom = Person("Tom", 22)
o parâmetro name
recebe "Tom", e age
recebe 22. A partir do nome do objeto, podemos acessar e modificar esses atributos.
Também podemos criar diferentes objetos da classe Person
, cada um com valores distintos para os atributos:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
tom = Person("Tom", 22)
bob = Person("Bob", 43)
print(tom.name) # Saída: Tom
print(bob.name) # Saída: Bob
Nesse exemplo, criamos dois objetos da classe Person
, tom
e bob
, que têm o mesmo conjunto de atributos, mas estados diferentes. Em cada caso, o Python define dinamicamente o objeto self
, seja para tom
ou bob
, conforme o contexto.
Não é obrigatório definir todos os atributos dentro da classe; Python permite a criação de atributos dinamicamente, fora do código da classe:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
tom = Person("Tom", 22)
tom.company = "Microsoft"
print(tom.company) # Saída: Microsoft
Aqui, o atributo company
foi adicionado dinamicamente. Contudo, isso pode lançar erros, pois tentar acessar um atributo antes de defini-lo resultará em erro:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
tom = Person("Tom", 22)
print(tom.company) # AttributeError: 'Person' object has no attribute 'company'
Métodos de Classe
Os métodos de uma classe são funções definidas dentro da classe que determinam seu comportamento. Vamos ver um exemplo com a classe Person
com um método simples:
class Person: # definição da classe Person
def say_hello(self):
print("Hello")
tom = Person()
tom.say_hello() # Saída: Hello
Aqui, definimos o método say_hello()
, que exibe uma saudação no console. Ao definir métodos em qualquer classe, o primeiro parâmetro é uma referência ao próprio objeto da classe, convencionalmente chamado de self
. Por meio de self
, podemos acessar o conteúdo do objeto atual. Esse parâmetro, no entanto, não é passado explicitamente ao chamar o método.
Usando o nome do objeto, podemos acessar seus métodos. Para isso, usamos a notação de ponto: escrevemos o nome do objeto seguido por um ponto e, em seguida, chamamos o método:
objeto.metodo([parâmetros opcionais do método])
Por exemplo, ao chamar o método say_hello()
para exibir a saudação:
tom.say_hello() # Saída: Hello
A execução do código acima exibe "Hello" no console.
Se o método precisar de outros parâmetros, eles são definidos após self
, e ao chamá-lo é necessário passar esses valores:
class Person: # definição da classe Person
def say(self, message): # método que recebe uma mensagem
print(message)
tom = Person()
tom.say("Hello Programício") # Saída: Hello Programício
Neste caso, say()
recebe dois parâmetros: self
e message
. No momento da chamada, o valor para message
deve ser informado.
Para acessar atributos e métodos do objeto dentro da própria classe, também usamos self
:
self.atributo # acessando um atributo
self.metodo() # chamando um método
Por exemplo, no seguinte código para a classe Person
:
class Person:
def __init__(self, name, age):
self.name = name # nome da pessoa
self.age = age # idade da pessoa
def display_info(self):
print(f"Name: {self.name@ Age: {self.age@")
tom = Person("Tom", 22)
tom.display_info() # Saída: Name: Tom Age: 22
bob = Person("Bob", 43)
bob.display_info() # Saída: Name: Bob Age: 43
Aqui, o método display_info()
exibe as informações do objeto no console. Para acessar os atributos do objeto dentro do método, usamos self
, como em self.name
e self.age
.
O resultado será:
Name: Tom Age: 22 Name: Bob Age: 43
Destrutores
Além dos construtores, as classes em Python podem ter métodos especiais chamados destrutores, que são chamados ao deletar um objeto. O destrutor é definido com o método __del__(self)
, que recebe uma referência ao objeto atual e permite executar ações específicas ao remover o objeto, como liberar ou apagar recursos.
O destrutor é chamado automaticamente pelo interpretador, e não precisamos chamá-lo manualmente. Aqui está um exemplo simples:
class Person:
def __init__(self, name):
self.name = name
print("Criada pessoa com o nome", self.name)
def __del__(self):
print("Removida pessoa com o nome", self.name)
tom = Person("Tom")
Neste exemplo, o destrutor exibe uma mensagem ao remover o objeto Person
. A criação do objeto tom
chama o construtor, e o destrutor é automaticamente chamado ao final do programa. A saída será:
Criada pessoa com o nome Tom Removida pessoa com o nome Tom
Outro exemplo:
class Person:
def __init__(self, name):
self.name = name
print("Criada pessoa com o nome", self.name)
def __del__(self):
print("Removida pessoa com o nome", self.name)
def create_person():
tom = Person("Tom")
create_person()
print("Fim do programa")
Aqui, o objeto Person
é criado e utilizado dentro da função create_person
, portanto sua existência é limitada ao escopo dessa função. Quando a função termina, o destrutor do objeto Person
é chamado. O console exibirá:
Criada pessoa com o nome Tom Removida pessoa com o nome Tom Fim do programa