À quoi sert l'attribut de propriété de Python ?

Prenez l'habitude d'écrire ensemble ! C'est le 9ème jour de ma participation au "Nuggets Daily New Plan · April Update Challenge", cliquez pour voir les détails de l'événement .

La notion d'attributs dynamiques Python peut être posée dans les entretiens, et elle est aussi très pratique dans les projets, mais elle ne sera pas évoquée dans les tutoriels de programmation générale, vous pourrez donc l'apprendre.

Commençons par un exemple simple. Créez une classe d'étudiants et je souhaite obtenir des informations sur chaque étudiant, y compris le nom, les notes, etc., via une instance. La note ne sera pas disponible tant que l'examen ne sera pas terminé, donc aucune valeur ne lui sera attribuée lors de son instanciation.

  
class Student:
    def __init__(self, name):
        self.name = name
        self.score = None

mike = Student('mike')
复制代码

Après l'examen, préparez-vous à évaluer Mike :

  
mike.score = 999
复制代码

Ici, l'enseignant a accidentellement tapé un 9 supplémentaire. En règle générale, le score est de 100. 999 est une donnée illégale et ne doit pas être attribuée avec succès. Lorsqu'il y a plus d'élèves, les enseignants feront plus d'erreurs dans la notation, nous devons donc trouver un moyen de modifier le programme pour limiter la valeur de la note à 0-100 points.

Valeur limite

Nous définissons une méthode, si l'entrée n'est pas un entier de 0 à 100, laissons le programme signaler une erreur, les données sont légales et nous modifions l'attribut score avec succès.

  
def set_score(self, new_score):
    if not isinstance(new_score, int):
        raise ValueError('score must be int')

    if 0 <= new_score <= 100:
        self.score = new_score
        return self.score
    else:
        raise ValueError('score invalid')
复制代码

De cette façon, nous utilisons self.score pour l'obtenir chaque fois que nous avons besoin d'obtenir le score, et appelons la fonction pour le modifier lorsque nous modifions le score :

  
mike.set_score(999)
复制代码

Une erreur sera signalée après l'appel, car 999 est une donnée illégale. Notez qu'à ce stade, je peux toujours utiliser self.score pour définir, et aucune erreur n'est signalée :

  
self.score = 999
复制代码

Cela ne fonctionne évidemment pas. Nous devons donc fournir un mécanisme pour transformer le score en une propriété privée inaccessible de l'extérieur. Malheureusement, les propriétés privées de Python sont pseudo-privées. Habituellement, nous appelons les attributs _en commençant par les attributs privés, mais il ne s'agit que d'un protocole et d'une réglementation. Si vous voyez des attributs commençant par un trait de soulignement, n'y accédez pas. Vous pouvez y accéder si vous insistez, mais python ne l'interdira pas.

Utilisez @propriété à la place.

Bien que la méthode ci-dessus implémente la fonction, elle modifie la façon dont l'attribut est utilisé. Il est généralement utilisé comme ceci :

  
# 获取属性
a = mike.score
# 设置属性
mike.score = 99

@property
def score(self):
    return self._score

@score.setter
def score(self, new_score):
    if not isinstance(new_score, int):
        raise ValueError('score must be int')

        if 0 <= new_score <= 100:
            self._score = new_score
            return self._score
        else:
            raise ValueError('score invalid')
复制代码

Avantages des propriétés dynamiques

  • La méthode d'appel est unifiée. La façon dont self.score = 99 , pas la façon dont la fonction appelle.
  • _scoreNous ne l'utiliserons pas directement. Vous pouvez l'utiliser, mais pas recommandé.
  • Si nous avons une propriété qui ne peut être qu'en lecture, commentez simplement la partie setter.

Terminons maintenant la classe en ajoutant les propriétés de naissance et d'âge :

  
from datetime import datetime

class Student:
    def __init__(self, name, birth=1920):
        self.name = name
        self._score = None
        self.birth = birth
        self.age = datetime.now().year - self.birth


mike = Student('mike')
print(mike.birth)
print(mike.age)
复制代码
  • La naissance et l'âge peuvent être calculés à partir de l'un et de l'autre. Il y a un problème de redondance des données.

  • La propriété d'âge est problématique comme ceci. Lorsque Mike est initialisé, l'âge a déjà été calculé. Si j'accède à la propriété age l'année prochaine, ce sera une valeur erronée. Cela peut être vérifié en définissant l'âge sur le nombre actuel de secondes :

      
    self.age = datetime.now().second
    
    mike = Student('mike')
    time.sleep(5)
    print(mike.age)
    print(datetime.now().second)
    复制代码

Affichage dynamique

  
@property
def age(self):
    return datetime.now().year - self.birth
复制代码

Remarque : ne définissez pas @age.setter ici, car il change de manière dynamique. Si vous le modifiez, cela entraînera une incohérence des données. Il ne peut être utilisé qu'en tant que propriété en lecture seule.

Rôle @property et scénarios d'application :

  • @property optimise la lisibilité de la lecture et du paramétrage des propriétés
  • Fonctionnalités qui doivent restreindre les attributs ;
  • Propriété en lecture seule. Si la propriété ne peut être qu'en lecture et non en écriture, elle est très pratique à utiliser.
  • Cette propriété change dynamiquement en fonction d'un environnement changeant.

Je suppose que tu aimes

Origine juejin.im/post/7084604734471929863
conseillé
Classement