1. __ Slots__
Si vous avez vu du code de GitHub, vous constaterez que de nombreuses grosses vaches ajoutent souvent __slots__ mots-clés en haut de la classe. Si vous êtes très curieux, vous pouvez essayer de faire fonctionner cette clé à nouveau, vous constaterez que rien ne se passe après l'avoir obtenu, tout est toujours très courant. Alors, quel est le mot clé __slots____?
Il avait principalement deux fonctions, a d'abord déclaré la première fonction, signifiant limiter l'utilisation des utilisateurs . Nous savons tous que Python est une langue dynamique très flexible , beaucoup de choses dans d'autres langues semblent être utilisées dans Python, c'est aussi le concept de conception de Python, d'avoir des effets de sacrifice pratiques et flexibles. Par exemple, envisagez un exemple très simple, car Python est la langue dynamique, le membre de la classe peut même être créé après la création de la classe. Ceci est absolument incapable dans la langue statique, nous ne pouvons que appeler des attributs existants dans la classe, qui est impossible ou difficile d'ajouterNouvelles propriétés.
Exemple:
class Exp: def __init__(self): self.a = None self.b = Noneif __name__ == "__main__": exp = Exp() exp.c = 3 print(exp.c)
Nous définissons une classe appelée exp, nous avons créé deux membres A et B pour cela. Mais lorsque nous utilisons,
nommer un membre de C. . Pour savoir que la classe EXP n'est pas membre C, mais le programme ne signale pas l'erreur, après notre exécution, il ajoutera C à ce cas.
D'un côté, cela est bien sûr très flexible, mais d'autre part, cela reste aussiDangers cachés
Si l'utilisateur ajoute des propriétés, ils peuvent conduire à des problèmes inconnus, en particulier dans des systèmes complexes. Donc, une heure de rigueur, nous ne voudrons pas que les utilisateurs effectuent cette modification dynamique. __slots__ l'habitude de faire cela. Nous ajoutons ce mot clé, le résultat est différent:
Si vous exécutez ce code, vous aurez une erreur.
class Exp: __slots__ = ['a', 'b'] def __init__(self): self.a = None self.b = Noneif __name__ == "__main__": exp = Exp() exp.c = 3 print(exp.c)
vous rappellera à propos de cet objet. Dans cet objet , c'est-à-dire que nous n'avons quePeut utiliser __SLOTS__, les membres sont définis dans ce mot-clé, ne peuvent pas être créés librement pour des membres non agréés et limités. Utilisateurs utilisent.
Bien que la plupart des gens utilisent cette clé pour utiliser cette clé pour signaler cette fin, malheureusement, l'intention initiale des créateurs de Python n'est pas ceci. Cela parlera du deuxième rôle de _slots__ mots-clés, qui est sauvegarde de la mémoire [1 doux-trois].
Si vous connaissez le principe de la classe inférieure de Python, vous constaterez que dans Python
Créer un dictionnaire , c'est un célèbre dictionnaire __dict__. C'est parce qu'il y a un dictionnaire derrière elle, afin que nous puissions créer un membre de l'original et soutenir cet effet dynamique. Nous pouvons appeler ce dictionnaire pour exporter du contenu, avant que nous ajoutons __slots__ mots-clés, la sortie de la sortie est comme ceci:
mais ajoutez cette réunion de mots-clés
Erreur , vous dira que Non __dict__. La raison est très simple, carUtilisation de dict pour maintenir une instance, consommez beaucoup de mémoire, ajoutez plus de données et après avoir utilisé __slots__, Python ne créera plus de dictionnaire pour une instance à maintenir, ce qui est une tableaux de taille fixe, ce qui permet de gagner beaucoup d'espace. Ces économies ne peuvent pas être un peu, généralement peuvent économiser plus de la moitié
. En d'autres termes, une certaine flexibilité est sacrifiée pour assurer la performance. C'est aussi __slots__ intention originale de concevoir ce mot clé, mais de nombreuses personnes ont maintenant mal utilisé l'emplacement.{'a': None, 'b': None}
Deuxièmement, la propriété Ce mot clé est mentionné dans l'article, mais il est très gêné à cause de la rédaction précédente de l'article, sa compréhension est également très limitée, ce qui provoque des explications, causant des explications, Cela prendra donc alors ce mot clé comme une compensation. L'hôtel peut nous aider
à lier l'affectation et acquiert certaines propriétés de la classe prise et définie. Prenons l'exemple:IciCh propriété sera fait lorsque nous appelons. Param et param.setter seront exécutés lorsque nous affectons une valeur à l'attribut Param. Donc, vous pouvez être étrange, pourquoi utiliser self.param = param dans la méthode __init__ au lieu de self._param = param, car nous allons appeler lorsque nous exécutons avant, python
appelle @ param.setter
Ce commentaire] Ce commentaire, nous n'avons donc pas à écrire dans le formulaire suivant. Bien sûr, vous pouvez également écrire cela, mais les deux sont complètement équivalents.
est un précédent programmeur Java toutes les variables de la classe Plus et des méthodes de fixation deviennent presque politiquement positives, j'aime particulièrement la production plus de talents pour tous les attributs de classe. Mais Ce n'est pas vrai , plus la propriété prend du temps, donc si vous ne voulez pas faire cela, nous appelons directement à attribuer une valeur. Si nécessaire, nous pouvons écrire la méthode pour recevoir et placer. Donc le problème vient, vÌ Ce n'est pas la norme, pourquoi utilisons-nous des propriétés?
class Exp: def __init__(self, param): self.param = param @property def param(self): return self._param @param.setter def param(self, value): self._param = value
La réponse est très simple et le type de variable est utilisé pour . Parce que Python est une langue dynamique et un type souterrain, nous ne savons pas quel type il aura et vous ne savez pas quel type d'utilisateur l'attribue. Donc, dans certains cas, nous pouvons vouloir faire une restriction, veuillez indiquer aux utilisateurs que seule cette variable peut être attribuée à ce type, sinon elle signalera l'erreur. En utilisant des propriétés, nous pouvons facilement faire cela.
De plus, l'attribut d'utilisation est au lieu de fonction . Par exemple: De cette manière, nous pouvons remplacer une fonction de .hello, il s'agit en fait d'un "calcul dynamique de
. Le résultat de Hello n'est pas stocké et ne sera exécuté que Lorsque nous l'appelons, et ce sera très pratique dans certaines scènes.
class Exp: def __init__(self, param): self.param = param @property def param(self): return self._param @param.setter def param(self, value): if not isinstance(value, str): raise TypeError('Want a string') self._param = value
Enfin, nous examinons la spécification de dénomination chez les objets Python. AshDes poteaux avancés, nous avons dit qu'il n'y avait pas de publicité publique et privée à Python. L'école est distinguée
toutes les écoles sont publiques , ce qui signifie que les utilisateurs peuvent obtenir tous les champs et méthodes de la classe. Pour normaliser, le programmeur est convaincu et tous ajoute la ligne suivante et les variables à voir privées
, même si nous pouvons appeler, mais en général, nous ne le faisons pas.class Exp: def __init__(self, param): self.param = param @property def param(self): return self._param @param.setter def param(self, value): if not isinstance(value, str): raise TypeError('Want a string') self._param = value @property def hello(self): return 'hello ' + self.param
Nous écrivons donc souvent deux méthodes, une méthode est une interface ouverte, l'une est un déploiement interne. Lorsque nous appelons, seules des interfaces publiques sont appelées et des interfaces publiques appelleront un déploiement interne. Cela est devenu une convention en python car nous passons souvent à des paramètres internes lors de l'appel des méthodes internes.
Considérons un exemple simple:En plus de _, nous en voyons souvent quelques
deux variables et méthodes ci-dessousla différence entre Que sont-ils? Pour répondre à la question hCeci, considérez l'exemple suivant: Que vais-je terminer? Essayez-la, la première ligne est la sortie de la part privée, ce n'est pas un problème. Mais quelles sont les deux prochaines personnes?
Deux est __private_func, mais
Le système changera automatiquement le nom. La raison de la modification du nom est également très simple, car Python
interdit strictement l'ajout de deux méthodes de soulignement à couvrir avec des sous-classes
. Par conséquent, la différence entre les deux est ici, elles sont considérées comme une méthode privée et un attribut, mais les sous-traitants permettent de couvrir les sous-classes, tandis que les souligneurs ne le sont pas. Donc, si nous voulons que nous soyons couverts par des sous-classes lorsque nous grandissons, nous devons ajouter deux soulignes.class ExpA: def __init__(self): pass def public_func(self): self._private_func() def _private_func(self): print('private ExpA')if __name__ == "__main__": exp = ExpA() exp.public_func()
Enfin, répondons à un petit problème. En C ++, lorsque le nom change et conflit de notre système, nous avons tendance à ajouter un _ pour distinguer la variable. Mais parce que sous la soulignement de Python a été donné un sens, nousJe ne peux pas faire cela, alors que dois-je faire lors du changement de conflit?La réponse est également très simple, nous pouvons ajouter le soulignement à l'arrière , telle que Lambda_.
class ExpA: def __init__(self): pass def public_func(self): self.__private_func() def __private_func(self): print('private ExpA')class ExpB(ExpA): def __init__(self): pass def public_func(self): self.__private_func() def __private_func(self): print('private ExpB')if __name__ == "__main__": exp = ExpB() exp.public_func() exp._ExpB__private_func() exp._ExpA__private_func()
Année, Résumé Examen du contenu d'aujourd'hui, principalement __slots__, propriété et soulignement en classe.Trois objets orientés Python
utilisent souvent des connaissances, la compréhension, ils peuvent non seulement écrire plus de code standard, mais nous aident également à comprendre la source d'autres gros vaches, ce qui est donc nécessaire.