Maison >développement back-end >Tutoriel Python >Structure de données Python : un Namedtuple sous-estimé (2)
La colonne
tutoriel vidéo Python continue de vous amener à comprendre la structure de données Namedtuple de Python.
Partie 1 Structure de données Python : un Namedtuple sous-estimé (1) Après avoir parlé d'une utilisation de base de Namedtuple, cet article continue.
Avant Python 3.7, un simple conteneur de données pouvait être créé à l'aide de l'une des méthodes suivantes :
attrs
Si vous souhaitez utiliser des cours réguliers, cela signifie que vous devrez mettre en œuvre quelques méthodes. Par exemple, une classe ordinaire aurait besoin d'une méthode __init__
pour définir les propriétés lors de l'instanciation de la classe. Si vous souhaitez que la classe soit hachable, cela signifie implémenter vous-même une méthode __hash__
. Afin de comparer différents objets, vous devez également implémenter une méthode __eq__
. Enfin, pour simplifier le débogage, vous avez besoin d'une méthode __repr__
.
Utilisons des cours réguliers pour mettre en œuvre notre cas d'utilisation des couleurs.
class Color: """A regular class that represents a color.""" def __init__(self, r, g, b, alpha=0.0): self.r = r self.g = g self.b = b self.alpha = alpha def __hash__(self): return hash((self.r, self.g, self.b, self.alpha)) def __repr__(self): return "{0}({1}, {2}, {3}, {4})".format( self.__class__.__name__, self.r, self.g, self.b, self.alpha ) def __eq__(self, other): if not isinstance(other, Color): return False return ( self.r == other.r and self.g == other.g and self.b == other.b and self.alpha == other.alpha )复制代码
Comme ci-dessus, vous devez implémenter de nombreuses méthodes. Vous avez juste besoin d’un conteneur pour conserver vos données sans vous soucier des détails gênants. Encore une fois, une différence clé dans la raison pour laquelle les gens préfèrent les classes d'implémentation est que les classes régulières sont mutables.
En fait, le PEP qui a introduit 数据类(Data Class)
les appelle des « tuples nommés mutables avec des valeurs par défaut » (Note du traducteur : classe de données introduite dans python 3.7, référence : docs.python.org/zh-cn / 3/lib…
Maintenant, voyons comment faire avec 数据类
from dataclasses import dataclass ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: float复制代码
Wow ! Puisqu'il n'y a pas de __init__
, il suffit de le suivre. . De plus, il doit être annoté avec des indications de type
En plus d'être mutable, la classe data peut fournir des champs facultatifs prêts à l'emploi. Disons que notre classe Color n'a pas besoin de champ alpha. peut faire en sorte que
from dataclasses import dataclassfrom typing import Optional ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: Optional[float]复制代码
l'instancier comme ceci :
>>> blue = Color(r=0, g=0, b=255)复制代码
Puisqu'ils sont mutables, nous pouvons modifier tous les champs que nous voulons. L'instancier comme ceci :
>>> blue = Color(r=0, g=0, b=255) >>> blue.r = 1 >>> # 可以设置更多的属性字段 >>> blue.e = 10复制代码
En revanche, <.> n'a pas de champs optionnels par défaut. Pour les ajouter, nous avons besoin d'une petite astuce et de quelques conseils de métaprogrammation : Pour ajouter une méthode namedtuple
, vous devez la rendre immuable en définissant
: __hash__
@dataclass(unsafe_hash=True)class Color: ...复制代码
unsafe_hash
Une autre différence est que le déballage est une fonctionnalité native des tuples nommés (citoyen de première classe) Si vous voulez True
avoir le même comportement, vous devez implémenter votre propre from dataclasses import dataclass, astuple ...@dataclassclass Color: """A regular class that represents a color.""" r: float g: float b: float alpha: float def __iter__(self): yield from dataclasses.astuple(self)复制代码
Comparaison des performances 数据类
. 🎜>
In [6]: import sys In [7]: ColorTuple = namedtuple("Color", "r g b alpha") In [8]: @dataclass ...: class ColorClass: ...: """A regular class that represents a color.""" ...: r: float ...: g: float ...: b: float ...: alpha: float ...: In [9]: color_tup = ColorTuple(r=50, g=205, b=50, alpha=1.0) In [10]: color_cls = ColorClass(r=50, g=205, b=50, alpha=1.0) In [11]: %timeit color_tup.r36.8 ns ± 0.109 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [12]: %timeit color_cls.r38.4 ns ± 0.112 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) In [15]: sys.getsizeof(color_tup) Out[15]: 72In [16]: sys.getsizeof(color_cls) + sys.getsizeof(vars(color_cls)) Out[16]: 152复制代码Comme ci-dessus, les données. les classes sont légèrement plus rapides pour accéder aux champs, mais elles sont nametuple et occupent plus d'espace mémoire Comment ajouter des indices de type à NametupleLes classes de données utilisent des indices de type par défaut. en les important sur des tuples nommés. En héritant de celui-ci, nous pouvons annoter des tuples de couleur
from typing import NamedTuple ...class Color(NamedTuple): """A namedtuple that represents a color.""" r: float g: float b: float alpha: float复制代码
Help on class Color in module __main__:class Color(builtins.tuple) | Color(r: float, g: float, b: float, alpha: Union[float, NoneType]) | | A namedtuple that represents a color. | | Method resolution order: | Color | builtins.tuple | builtins.object | | Methods defined here: | | __getnewargs__(self) | Return self as a plain tuple. Used by copy and pickle. | | __repr__(self) | Return a nicely formatted representation string | | _asdict(self) | Return a new dict which maps field names to their values.复制代码Comment ajouter une valeur facultative par défaut à nomméetupleDans la section précédente, nous avons appris que les classes de données peuvent avoir des valeurs facultatives. Aussi, j'ai mentionné que pour imiter le même comportement
from collections import namedtupleclass Color(namedtuple("Color", "r g b alpha")): __slots__ = () def __new__(cls, r, g, b, alpha=None): return super().__new__(cls, r, g, b, alpha)>>> c = Color(r=0, g=0, b=0)>>> c Color(r=0, g=0, b=0, alpha=None)复制代码
Conclusionnamedtuple
数据类
namedtuples
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!