Hash cohérent()
Citation de tangerv le 22 août 2024, 14 h 57 minJe suis en train de coder des classes et je souhaite définir la méthode __hash__ afin de l'utiliser pour créer des identifiants cohérents pour les objets de ces classes, de sorte que si leur structure de données (certaines autres variables d'instance) ne change pas, l'identifiant reste le même. Cependant, en utilisant hash(), j'ai compris par essais et erreurs qu'il change à chaque exécution de Python. Existe-t-il une solution pythonique pour gérer ce cas d'utilisation ?
Par exemple, j'essaie ceci, mais je suis encore en train de déboguer des erreurs d'exécution dues à la complexité de la gestion des int, str ou bytes avec les différentes fonctions.
from typing import List, Optional, Union from pydantic import BaseModel, Field, computed_field import hashlib import base64 class File(BaseModel): filename: str content: Optional[Union[str, bytes]] = None encoding: Optional[str] = None id_attachment: Optional[str] = Field(default=None, init=False) @computed_field @property def extension(self) -> str: return os_split_extension(self.filename)[-1].lower() def __hash__(self): if isinstance(self.content, str): # Decode content if it's base64 encoded content_bytes = base64.b64decode(self.content) else: content_bytes = self.content or b'' # Concatenate filename and content bytes hash_input = self.filename.encode() + content_bytes return int.from_bytes(hashlib.sha256(hash_input).digest(), byteorder='big') class EmailAddress(BaseModel): nickname: Optional[str] = None address: str def __str__(self): return self.address def __hash__(self): # Concatenate nickname and andress hash_input = (self.nickname or "").encode() + self.address.encode() return int.from_bytes(hashlib.sha256(hash_input).digest(), byteorder='big')
Je n'aime pas vraiment mon code car il ne me semble pas propre et semble sujet aux erreurs. Comment puis-je être plus cohérent ici ? Puis-je exploiter des bibliothèques ou des méthodes pythoniennes pour mieux gérer cela ?
Je souhaite également construire d'autres modèles à partir de ceux-ci, par exemple. Dois-je enregistrer le hash d'une manière ou d'une autre afin de construire le hash du modèle composite en récupérant les hash des modèles de variables d'instance ?
Je suis en train de coder des classes et je souhaite définir la méthode __hash__ afin de l'utiliser pour créer des identifiants cohérents pour les objets de ces classes, de sorte que si leur structure de données (certaines autres variables d'instance) ne change pas, l'identifiant reste le même. Cependant, en utilisant hash(), j'ai compris par essais et erreurs qu'il change à chaque exécution de Python. Existe-t-il une solution pythonique pour gérer ce cas d'utilisation ?
Par exemple, j'essaie ceci, mais je suis encore en train de déboguer des erreurs d'exécution dues à la complexité de la gestion des int, str ou bytes avec les différentes fonctions.
from typing import List, Optional, Union from pydantic import BaseModel, Field, computed_field import hashlib import base64 class File(BaseModel): filename: str content: Optional[Union[str, bytes]] = None encoding: Optional[str] = None id_attachment: Optional[str] = Field(default=None, init=False) @computed_field @property def extension(self) -> str: return os_split_extension(self.filename)[-1].lower() def __hash__(self): if isinstance(self.content, str): # Decode content if it's base64 encoded content_bytes = base64.b64decode(self.content) else: content_bytes = self.content or b'' # Concatenate filename and content bytes hash_input = self.filename.encode() + content_bytes return int.from_bytes(hashlib.sha256(hash_input).digest(), byteorder='big') class EmailAddress(BaseModel): nickname: Optional[str] = None address: str def __str__(self): return self.address def __hash__(self): # Concatenate nickname and andress hash_input = (self.nickname or "").encode() + self.address.encode() return int.from_bytes(hashlib.sha256(hash_input).digest(), byteorder='big')
Je n'aime pas vraiment mon code car il ne me semble pas propre et semble sujet aux erreurs. Comment puis-je être plus cohérent ici ? Puis-je exploiter des bibliothèques ou des méthodes pythoniennes pour mieux gérer cela ?
Je souhaite également construire d'autres modèles à partir de ceux-ci, par exemple. Dois-je enregistrer le hash d'une manière ou d'une autre afin de construire le hash du modèle composite en récupérant les hash des modèles de variables d'instance ?
Citation de dominator le 22 août 2024, 16 h 01 minJe recommanderais la bibliothèque attrs. Si vous acceptez de geler la classe, vous pouvez avoir un hachage qui devrait être invariant entre les sessions. Si vous ne souhaitez pas geler la classe, le hachage le plus raisonnable dépend du pointeur vers l'objet, qui ne sera pas indépendant entre les sessions. Un hack auquel je peux penser est de créer une copie gelée de votre objet, puis de calculer le hachage de cet objet. Mais cela semble être une mauvaise idée d'implémenter un tel hack dans __hash__.
Cela ne fait que demander des bugs et des erreurs.
Je recommanderais la bibliothèque attrs. Si vous acceptez de geler la classe, vous pouvez avoir un hachage qui devrait être invariant entre les sessions. Si vous ne souhaitez pas geler la classe, le hachage le plus raisonnable dépend du pointeur vers l'objet, qui ne sera pas indépendant entre les sessions. Un hack auquel je peux penser est de créer une copie gelée de votre objet, puis de calculer le hachage de cet objet. Mais cela semble être une mauvaise idée d'implémenter un tel hack dans __hash__.
Cela ne fait que demander des bugs et des erreurs.