Maison >développement back-end >Tutoriel Python >Explication détaillée du décorateur dataclass, une nouvelle fonctionnalité de Python 3.7

Explication détaillée du décorateur dataclass, une nouvelle fonctionnalité de Python 3.7

不言
不言original
2018-04-21 14:44:591780parcourir

Cet article vous présente principalement les informations pertinentes sur la nouvelle fonction de Python 3.7, le décorateur de classe de données. L'article la présente en détail à travers un exemple de code. Il a une certaine valeur d'apprentissage de référence pour les études ou le travail de tous les amis qui en ont besoin. il Apprenons ensemble.

Préface

Python 3.7 sortira cet été, et il y aura beaucoup de nouveautés dans Python 3.7 :

  • Diverses améliorations du jeu de caractères

  • Évaluation différée des annotations

  • et prise en charge des classes de données

L'une des nouvelles fonctionnalités les plus intéressantes est le décorateur dataclass.

Qu'est-ce que la classe de données

La plupart des développeurs Python ont écrit de nombreuses classes comme celles-ci :

class MyClass:
 def __init__(self, var_a, var_b):
 self.var_a = var_a
 self.var_b = var_b

dataclass peut générer automatiquement des méthodes pour des cas simples, par exemple, un __init__ accepte ces paramètres et se les attribue, le petit exemple précédent peut être réécrit comme :

@dataclass
class MyClass:
 var_a: str
 var_b: str

Voyons comment l'utiliser à travers un exemple

API Star Wars

Vous pouvez utiliser des requêtes pour obtenir des ressources de l'API Star Wars :

response = requests.get('https://swapi.co/api/films/1/')
dictionary = response.json()

Jetons un coup d'œil au dictionnaire (simplifié) Le résultat de :

{
 'characters': ['https://swapi.co/api/people/1/',… ],
 'created': '2014-12-10T14:23:31.880000Z',
 'director': 'George Lucas',
 'edited': '2015-04-11T09:46:52.774897Z',
 'episode_id': 4,
 'opening_crawl': 'It is a period of civil war.\r\n … ',
 'planets': ['https://swapi.co/api/planets/2/', … ],
 'producer': 'Gary Kurtz, Rick McCallum',
 'release_date': '1977-05-25',
 'species': ['https://swapi.co/api/species/5/',…],
 'starships': ['https://swapi.co/api/starships/2/',…],
 'title': 'A New Hope',
 'url': 'https://swapi.co/api/films/1/',
 'vehicles': ['https://swapi.co/api/vehicles/4/',…]

Encapsulation d'API

Afin d'encapsuler correctement un API , nous devrions créer un objet que les utilisateurs peuvent utiliser dans leurs applications, donc dans Python 3.6 définir un objet pour contenir les réponses aux requêtes à /films/endpoint :

class StarWarsMovie:
 def __init__(self,
   title: str,
   episode_id: int,
   opening_crawl: str,
   director: str,
   producer: str,
   release_date: datetime,
   characters: List[str],
   planets: List[str],
   starships: List[str],
   vehicles: List[str],
   species: List[str],
   created: datetime,
   edited: datetime,
   url: str
   ):

 self.title = title
 self.episode_id = episode_id
 self.opening_crawl= opening_crawl
 self.director = director
 self.producer = producer
 self.release_date = release_date
 self.characters = characters
 self.planets = planets
 self.starships = starships
 self.vehicles = vehicles
 self.species = species
 self.created = created
 self.edited = edited
 self.url = url

 if type(self.release_date) is str:
  self.release_date = dateutil.parser.parse(self.release_date)

 if type(self.created) is str:
  self.created = dateutil.parser.parse(self.created)

 if type(self.edited) is str:
  self.edited = dateutil.parser.parse(self.edited)

Les lecteurs attentifs auront peut-être remarqué du code répété ici.

C'est un cas classique d'utilisation du décorateur dataclass, nous devons créer une classe qui est principalement utilisée pour contenir des données, avec juste un peu de validation, voyons donc ce que nous devons modifier.

Tout d'abord, la classe de données génère automatiquement certaines méthodes dunder. Si nous ne spécifions aucune option pour le décorateur de classe de données, les méthodes générées sont : __init__, __eq__ et __repr__, si vous avez défini __repr__ Mais __str__ ne l'est pas. défini, et par défaut Python (pas seulement les classes de données) implémentera la méthode de sortie __str__ qui renvoie __repr__. Par conséquent, les quatre méthodes dunder peuvent être implémentées en modifiant simplement le code comme suit :

@dataclass
class StarWarsMovie:
 title: str
 episode_id: int
 opening_crawl: str
 director: str
 producer: str
 release_date: datetime
 characters: List[str]
 planets: List[str]
 starships: List[str]
 vehicles: List[str]
 species: List[str]
 created: datetime
 edited: datetime
 url: str

Nous avons supprimé la méthode __init__ pour garantir que les données A le décorateur de classe peut ajouter les méthodes correspondantes qu'il génère. Cependant, nous avons perdu certaines fonctionnalités au cours du processus, notre constructeur Python 3.6 définit non seulement toutes les valeurs, mais tente également d'analyser la date, comment pouvons-nous faire cela avec une classe de données ?

Si nous voulons remplacer __init__, nous perdrons l'avantage de la classe de données, donc si nous voulons gérer des fonctionnalités supplémentaires, nous pouvons utiliser la nouvelle méthode dunder : __post_init__, voyons la méthode __post_init__ pour notre classe wrapper. est-ce que ça ressemble à :

def __post_init__(self):
 if type(self.release_date) is str:
  self.release_date = dateutil.parser.parse(self.release_date)

 if type(self.created) is str:
  self.created = dateutil.parser.parse(self.created)

 if type(self.edited) is str:
  self.edited = dateutil.parser.parse(self.edited)

C'est ça ! Nous pouvons utiliser le décorateur de classe de données pour implémenter notre classe dans les deux tiers du code.

Plus de goodies

La classe de données peut être davantage personnalisée pour le cas d'utilisation en utilisant les options du décorateur, les options par défaut sont :

@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

  • init détermine s'il faut générer __init__ méthode dunder

  • repr détermine s'il faut générer La méthode __repr__ dunder

  • eq fait de même pour la méthode __eq__ dunder, qui détermine le comportement de la vérification d'égalité (your_class_instance == another_instance)

  • order actual Il existe quatre méthodes dunder créées sur , qui déterminent le comportement de toutes les vérifications inférieures à, et/ou supérieures à, et si elles sont définies sur true, la liste des objets peut être triée.

Les deux dernières options déterminent si l'objet peut être haché, ce qui est nécessaire si vous souhaitez utiliser des objets de votre classe comme clés de dictionnaire.

Pour plus d'informations, veuillez vous référer à : PEP 557 -- Classes de données


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn