Procurando começar com o design orientado a objetos em Python? Dê os primeiros passos hoje aprendendo sobre o método __init__ do Python.
Neste tutorial, examinaremos os fundamentos das classes e objetos do Python e, em seguida, aprenderemos sobre o método __init__.
Ao final deste tutorial, você será capaz de responder às seguintes perguntas:
- O que são variáveis de instância ou atributos de instância?
- Como o método init ajuda na inicialização dos atributos da instância?
- Como podemos definir valores padrão para atributos?
- Como podemos usar métodos de classe como construtores para criar objetos?
Vamos começar.
últimas postagens
Classes e objetos do Python
As classes são fundamentais para a programação orientada a objetos em Python. Podemos criar uma classe e definir atributos e métodos — para vincular dados e funcionalidades associadas.
Depois de criar uma classe, podemos usá-la como um projeto (ou modelo) para criar objetos (instâncias).
👩🏫Tempo de exemplo! Vamos criar uma classe Employee onde cada objeto desta classe possui os seguintes atributos:
- full_name: o nome completo do funcionário no formato firstName lastName
- emp_id: o id do funcionário
- departamento: o departamento a que pertencem
- experiência: o número de anos de experiência que eles têm
O que isto significa? 🤔
Cada funcionário individual será uma instância ou objeto da classe Employee. E cada objeto terá seu próprio valor para full_name, emp_id, departamento e experiência.
Esses atributos também são chamados de variáveis de instância e usaremos os termos atributos e variáveis de instância de forma intercambiável.
Em breve adicionaremos atributos. Por enquanto, criamos uma classe Employee da seguinte forma:
class Employee: pass
Usar pass (como espaço reservado) nos ajuda a evitar erros ao executar o script.
Embora a versão atual da classe Employee não seja muito útil, ainda é uma classe válida. Assim podemos criar objetos da classe Employee:
employee_1 = Employee() print(employee_1) #Output: <__main__.Employee object at 0x00FEE7F0>
Podemos também adicionar atributos e inicializá-los com valores como mostrado:
employee_1.full_name="Amy Bell" employee_1.department="HR"
Mas essa abordagem para adicionar atributos de instância é ineficiente e propensa a erros. Além disso, isso não permite o uso de classe como modelo para criar objetos. Aqui é onde o método __init__ ajuda.
Compreendendo o papel do método __init__ em uma classe Python
Devemos ser capazes de inicializar as variáveis de instância ao instanciar um objeto e o método __init__ nos ajuda a fazer isso. O método __init__ é chamado toda vez que um novo objeto da classe é criado para inicializar os valores das variáveis de instância.
Se você programou em uma linguagem como C++, verá que o método __init__ funciona de maneira semelhante aos construtores.
Definindo o método __init__
Vamos adicionar o método __init__ à classe Employee:
class Employee: def __init__(self, full_name,emp_id,department,experience): self.full_name = full_name self.emp_id = emp_id self.department = department self.experience = experience
O parâmetro self refere-se à instância da classe e self.attribute inicializa o atributo de instância com o valor do lado direito.
Agora podemos criar objetos assim:
employee_2 = Employee('Bella Joy','M007','Marketing',3) print(employee_2) # Output: <__main__.Employee object at 0x017F88B0>
Quando imprimimos os objetos empregados, não obtemos nenhuma informação útil, exceto a classe a que pertencem. Vamos adicionar um método __repr__ que define uma string de representação para a classe:
def __repr__(self): return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."
Adicionando o __repr__ à classe Employee, temos:
class Employee: def __init__(self, full_name,emp_id,department,experience): self.full_name = full_name self.emp_id = emp_id self.department = department self.experience = experience def __repr__(self): return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."
Agora os objetos do funcionário têm uma string de representação útil:
print(employee_2) # Output: Bella Joy,M007 from Marketing with 3 years of experience.
Algumas Convenções
Antes de prosseguirmos, aqui estão algumas notas:
- Usamos self como o primeiro parâmetro no método __init__ para nos referirmos à própria instância da classe e usamos self.attribute_name para inicializar os vários atributos. Usar self é a convenção preferida (você pode usar qualquer outro nome).
- Ao definir o método __init__, definimos os nomes dos parâmetros nas definições __init__ para corresponder aos nomes dos atributos. Isso melhora a legibilidade.
Como adicionar valores padrão para atributos
No exemplo que codificamos até agora, todos os atributos são obrigatórios. Significa que a criação do objeto é bem-sucedida somente se passarmos os valores de todos os campos para o construtor.
Tente instanciar um objeto da classe Employee sem passar o valor para o atributo experience:
employee_3 = Employee('Jake Lee','E001','Engineering')
Você obterá o seguinte erro:
Traceback (most recent call last): File "main.py", line 22, in <module> employee_3 = Employee('Jake Lee','E001','Engineering') TypeError: __init__() missing 1 required positional argument: 'experience'
Mas se você quiser tornar determinados atributos opcionais, poderá fazê-lo fornecendo valores padrão para esses atributos ao definir o método __init__.
Aqui fornecemos um valor padrão de 0 para o atributo de experiência:
class Employee: def __init__(self, full_name,emp_id,department,experience=0): self.full_name = full_name self.emp_id = emp_id self.department = department self.experience = experience def __repr__(self): return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."
O objeto employee_3 é criado sem valor para o atributo experience; o valor padrão de 0 é usado para experiência.
employee_3 = Employee('Jake Lee','E001','Engineering') print(employee_3.experience) # Output: 0
Construtores de classe alternativos usando métodos de classe
Até agora, vimos apenas como definir o método __init__ e definir valores padrão para atributos quando necessário. Também sabemos que precisamos passar os valores para os atributos necessários no construtor.
Às vezes, no entanto, os valores dessas variáveis de instância (ou atributos) podem estar disponíveis em uma estrutura de dados diferente, como uma tupla, um dicionário ou uma string JSON.
Então, o que fazemos?
Vamos dar um exemplo. Suponha que tenhamos valores da variável de instância em um dicionário Python:
dict_fanny = {'name':'Fanny Walker','id':'H203','dept':'HR','exp':2}
Podemos acessar o dicionário e obter todos os atributos da seguinte forma:
name = dict_fanny['name'] id = dict_fanny['id'] dept = dict_fanny['dept'] exp = dict_fanny['exp']
Depois disso, você pode criar um objeto passando esses valores para o construtor da classe:
employee_4 = Employee(name, id, dept, exp) print(employee_4) # Output: Fanny Walker,H203 from HR with 2 years of experience.
Lembre-se: você precisa fazer isso para cada novo objeto que criar. Essa abordagem é ineficiente e definitivamente podemos fazer melhor. Mas como?
Em Python, podemos usar métodos de classe como construtores para criar objetos da classe. Para criar um método de classe, usamos o decorador @classmethod.
Vamos definir um método que analise o dicionário, obtenha os valores das variáveis de instância e os use para construir objetos Employee.
@classmethod def from_dict(cls,data_dict): full_name = data_dict['name'] emp_id = data_dict['id'] department = data_dict['dept'] experience = data_dict['exp'] return cls(full_name, emp_id, department, experience)
Quando precisamos criar objetos usando dados do dicionário, podemos usar o método da classe from_dict().
💡 Observe o uso de cls no método da classe ao invés de self. Da mesma forma que usamos self para nos referirmos à instância, cls é usado para nos referirmos à classe. Além disso, os métodos de classe são vinculados à classe e não aos objetos.
Então, quando chamamos o método de classe from_dict() para criar objetos, nós o chamamos na classe Employee:
emp_dict = {'name':'Tia Bell','id':'S270','dept':'Sales','exp':3} employee_5 = Employee.from_dict(emp_dict) print(employee_5) # Output: Tia Bell,S270 from Sales with 3 years of experience.
Agora, se tivermos um dicionário para cada um dos n funcionários, podemos usar o método de classe from_dict() como um construtor para instanciar objetos — sem precisar recuperar os valores de variáveis instantâneas do dicionário.
📝Uma observação sobre variáveis de classe
Aqui definimos o método de classe que está vinculado à classe e não às instâncias individuais. Semelhante aos métodos de classe, também podemos ter variáveis de classe.
Assim como os métodos de classe, as variáveis de classe são vinculadas à classe e não a uma instância. Quando um atributo assume um valor fixo para todas as instâncias da classe, podemos considerar defini-los como variáveis de classe.
perguntas frequentes
1. Por que você precisa do método __init__ em Python?
O método __init__ em uma definição de classe nos permite inicializar os atributos ou variáveis de instância de todas as instâncias da classe. O método __init__ é chamado sempre que uma nova instância da classe é criada.
2. Você pode ter vários métodos __init__ em uma classe Python?
O objetivo de ter vários métodos __init__ em uma classe Python é fornecer vários construtores que instanciam objetos. Mas você não pode definir vários métodos __init__. Se você definir vários métodos __init__, a segunda e mais recente implementação substituirá a primeira. No entanto, você pode usar o decorador @classmethod para definir métodos de classe que podem ser usados como construtores para instanciar objetos.
3. O que acontece se você não definir o método __init__ em uma classe?
Se você não definir o método __init__, ainda poderá instanciar objetos. No entanto, você terá que adicionar variáveis de instância manualmente e atribuir valores a cada uma delas. Você não poderá passar os valores para as variáveis de instância no construtor. Isso não apenas é propenso a erros, mas também anula o propósito de ter a classe como um modelo a partir do qual podemos instanciar objetos.
4. Você pode ter valores padrão para argumentos no método __init__?
Sim, é possível fornecer valores padrão para um ou mais atributos ao definir o método __init__. Fornecer valores padrão ajuda a tornar esses atributos opcionais no construtor. Os atributos assumem os valores padrão quando não passamos os valores para esses atributos no construtor.
5. Você pode modificar atributos fora do método __init__?
Sim, você sempre pode atualizar o valor de um atributo fora do método __init__. Você também pode adicionar novos atributos dinamicamente a uma instância depois de criar a instância específica.
Conclusão
Neste tutorial, aprendemos como usar o método __init__ para inicializar os valores das variáveis de instância. Embora isso seja direto, pode ser repetitivo – especialmente quando você tem muitos atributos.
Se estiver interessado, você pode explorar o módulo dataclasses. No Python 3.7 e posterior, você pode usar o módulo integrado de classes de dados para criar classes de dados que armazenam dados. Além das implementações padrão do __init__ e outros métodos comumente usados; eles vêm com muitos recursos interessantes para dicas de tipo, valores padrão complexos e otimização.
A seguir, aprenda mais sobre if __name__==’__main__’ em Python.