How does the @property decorator work in Python?

后端 未结 13 2128
闹比i
闹比i 2020-11-21 04:49

I would like to understand how the built-in function property works. What confuses me is that property can also be used as a decorator, but it only

13条回答
  •  一个人的身影
    2020-11-21 05:27

    I read all the posts here and realized that we may need a real life example. Why, actually, we have @property? So, consider a Flask app where you use authentication system. You declare a model User in models.py:

    class User(UserMixin, db.Model):
        __tablename__ = 'users'
        id = db.Column(db.Integer, primary_key=True)
        email = db.Column(db.String(64), unique=True, index=True)
        username = db.Column(db.String(64), unique=True, index=True)
        password_hash = db.Column(db.String(128))
    
        ...
    
        @property
        def password(self):
            raise AttributeError('password is not a readable attribute')
    
        @password.setter
        def password(self, password):
            self.password_hash = generate_password_hash(password)
    
        def verify_password(self, password):
            return check_password_hash(self.password_hash, password)
    

    In this code we've "hidden" attribute password by using @property which triggers AttributeError assertion when you try to access it directly, while we used @property.setter to set the actual instance variable password_hash.

    Now in auth/views.py we can instantiate a User with:

    ...
    @auth.route('/register', methods=['GET', 'POST'])
    def register():
        form = RegisterForm()
        if form.validate_on_submit():
            user = User(email=form.email.data,
                        username=form.username.data,
                        password=form.password.data)
            db.session.add(user)
            db.session.commit()
    ...
    

    Notice attribute password that comes from a registration form when a user fills the form. Password confirmation happens on the front end with EqualTo('password', message='Passwords must match') (in case if you are wondering, but it's a different topic related Flask forms).

    I hope this example will be useful

提交回复
热议问题