Resumo : neste tutorial, você aprenderá sobre as classes mixin do Python e como usá-las para tornar o código reutilizável.
O que é um mixin em Python
Um mixin é uma classe que fornece implementações de métodos para reutilização por várias classes filhas relacionadas. No entanto, a herança não implica um relacionamento é-um.
Um mixin não define um novo tipo. Portanto, não se destina à instanciação de direção.
Um mixin agrupa um conjunto de métodos para reutilização. Cada mixin deve ter um único comportamento específico, implementando métodos intimamente relacionados.
Normalmente, uma classe filha usa herança múltipla para combinar as classes mixin com uma classe pai.
Como o Python não define uma maneira formal de definir classes mixin, é uma boa prática nomear classes mixin com o sufixo Mixin
.
Uma classe mixin é como uma interface em Java e C# com implementação. E é como uma característica do PHP .
Exemplo de mixagem em Python
Primeiro, defina uma Person
classe:
class Person:
def __init__(self, name):
self.name = name
Linguagem de código: Python ( python )
Segundo, defina uma Employee
classe que herda da Person
classe:
class Employee(Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependents
Linguagem de código: Python ( python )
Terceiro, crie uma nova instância da Employee
classe:
if __name__ == '__main__':
e = Employee(
name='John',
skills=['Python Programming''Project Management'],
dependents={'wife': 'Jane', 'children': ['Alice', 'Bob']}
)
Linguagem de código: Python ( python )
Suponha que você queira converter o Employee
objeto em um dicionário . Para fazer isso, você pode adicionar um novo método à Employee
classe, que converte o objeto em um dicionário.
Entretanto, você pode querer converter objetos de outras classes em dicionários . Para tornar o código reutilizável, você pode definir uma classe mixin chamada DictMixin
como a seguir:
class DictMixin:
def to_dict(self):
return self._traverse_dict(self.__dict__)
def _traverse_dict(self, attributes: dict) -> dict:
result = {}
for key, value in attributes.items():
result[key] = self._traverse(key, value)
return result
def _traverse(self, key, value):
if isinstance(value, DictMixin):
return value.to_dict()
elif isinstance(value, dict):
return self._traverse_dict(value)
elif isinstance(value, list):
return [self._traverse(key, v) for v in value]
elif hasattr(value, '__dict__'):
return self._traverse_dict(value.__dict__)
else:
return value
Linguagem de código: Python ( python )
A DictMixin
classe possui o to_dict()
método que converte um objeto em um dicionário.
O _traverse_dict()
método itera os atributos do objeto e atribui a chave e o valor ao resultado.
O atributo de um objeto pode ser uma lista, um dicionário ou um objeto com o __dict__
atributo. Portanto, o _traverse_dict()
método usa o _traverse()
método para converter o atributo em valor.
Para converter instâncias da Employee
classe em dicionários, é Employee
necessário herdar das classes DictMixin
e :Person
class Employee(DictMixin, Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependents
Linguagem de código: Python ( python )
Observe que você precisa especificar as classes mixin antes de outras classes.
O seguinte procedimento cria uma nova instância da Employee
classe e a converte em um dicionário:
e = Employee(
name='John',
skills=['Python Programming', 'Project Management'],
dependents={'wife': 'Jane', 'children': ['Alice', 'Bob']}
)
pprint(e.to_dict())
Linguagem de código: Python ( python )
Saída:
{'dependents': {'children': ['Alice', 'Bob'], 'wife': 'Jane'},
'name': 'John',
'skills': ['Python Programming', 'Project Management']}
Linguagem de código: Python ( python )
O seguinte mostra o código completo:
from pprint import pprint
class DictMixin:
def to_dict(self):
return self._traverse_dict(self.__dict__)
def _traverse_dict(self, attributes):
result = {}
for key, value in attributes.items():
result[key] = self._traverse(key, value)
return result
def _traverse(self, key, value):
if isinstance(value, DictMixin):
return value.to_dict()
elif isinstance(value, dict):
return self._traverse_dict(value)
elif isinstance(value, list):
return [self._traverse(key, v) for v in value]
elif hasattr(value, '__dict__'):
return self._traverse_dict(value.__dict__)
else:
return value
class Person:
def __init__(self, name):
self.name = name
class Employee(DictMixin, Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependents
if __name__ == '__main__':
e = Employee(
name='John',
skills=['Python Programming', 'Project Management'],
dependents={'wife': 'Jane', 'children': ['Alice', 'Bob']}
)
pprint(e.to_dict())
Linguagem de código: Python ( python )
Componha várias classes mixin
Suponha que você queira converter o Employee
objeto do para JSON. Para fazer isso, você pode primeiro definir uma nova classe mixin que use o json
módulo padrão:
import json
class JSONMixin:
def to_json(self):
return json.dumps(self.to_dict())
Linguagem de código: Python ( python )
E então mude a Employee
classe para que ela herde a JSONMixin
classe:
class Employee(DictMixin, JSONMixin, Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependents
Linguagem de código: Python ( python )
O seguinte cria uma nova instância da Employee
classe e a converte em um dicionário e json:
if __name__ == '__main__':
e = Employee(
name='John',
skills=['Python Programming''Project Management'],
dependents={'wife': 'Jane', 'children': ['Alice', 'Bob']}
)
pprint(e.to_dict())
print(e.to_json())
Linguagem de código: Python ( python )
Saída:
{'dependents': {'children': ['Alice', 'Bob'], 'wife': 'Jane'},
'name': 'John',
'skills': ['Python ProgrammingProject Management']}
{"name": "John", "skills": ["Python ProgrammingProject Management"], "dependents": {"wife": "Jane", "children": ["Alice", "Bob"]}}
Linguagem de código: Python ( python )
O seguinte mostra o código completo:
import json
from pprint import pprint
class DictMixin:
def to_dict(self):
return self._traverse_dict(self.__dict__)
def _traverse_dict(self, attributes):
result = {}
for key, value in attributes.items():
result[key] = self._traverse(key, value)
return result
def _traverse(self, key, value):
if isinstance(value, DictMixin):
return value.to_dict()
elif isinstance(value, dict):
return self._traverse_dict(value)
elif isinstance(value, list):
return [self._traverse(key, v) for v in value]
elif hasattr(value, '__dict__'):
return self._traverse_dict(value.__dict__)
else:
return value
class JSONMixin:
def to_json(self):
return json.dumps(self.to_dict())
class Person:
def __init__(self, name):
self.name = name
class Employee(DictMixin, JSONMixin, Person):
def __init__(self, name, skills, dependents):
super().__init__(name)
self.skills = skills
self.dependents = dependents
if __name__ == '__main__':
e = Employee(
name='John',
skills=['Python Programming''Project Management'],
dependents={'wife': 'Jane', 'children': ['Alice', 'Bob']}
)
pprint(e.to_dict())
print(e.to_json())
Linguagem de código: Python ( python )
Resumo
- Uma classe mixin fornece implementações de métodos para reutilização por múltiplas subclasses relacionadas.