Python Flask Web - User模型赋予角色的构造函数

《Flask Web开发》在9.2节中,对于用户的角色赋予是通过在User模型的构造函数中完成的

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)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    password_hash = db.Column(db.String(128))
    confirmed = db.Column(db.Boolean,default = False)
    name = db.Column(db.String(64))
    location = db.Column(db.String(64))
    about_me = db.Column(db.Text())
    member_since = db.Column(db.DateTime(),default = datetime.utcnow)
    last_seen = db.Column(db.DateTime(),default = datetime.utcnow)

    def __init__(self,**kwargs):
        super(User,self).__init__(**kwargs)
        if self.role is None:
            if self.email == current_app.config['FLASKY_ADMIN']:
                self.role = Role.query.filter_by(name = 'Administrator').first()
            if self.role is None:
                self.role = Role.query.filter_by(default = True).first()

学习的时候一直卡在super(User,self).__init__(**kwargs)这一行代码上。为什么User模型的构造函数为什么要调用父类的构造函数?它调用的是父类UserMixin还是db.Model的?

自己想了好久,一直没有想明白。后来再回去复习了一下super函数的关于类的继承,突然间豁然开朗了。Python子类的初始化不会自动地调用父类的初始化。使用super函数可以根据MRO实现父类的代理,这里就是调用了父类的构造函数__init__进行初始化。如果不显式地调用该方法,则父类的构造函数就会被子类的构造函数重写,父类的属性在子类的实例中就会缺失

class UserMixin(object):
    '''
    This provides default implementations for the methods that Flask-Login
    expects user objects to have.
    '''
    @property
    def is_active(self):
        return True

    @property
    def is_authenticated(self):
        return True

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        try:
            return unicode(self.id)
        except AttributeError:
            raise NotImplementedError('No `id` attribute - override `get_id`')

    def __eq__(self, other):
        '''
        Checks the equality of two `UserMixin` objects using `get_id`.
        '''
        if isinstance(other, UserMixin):
            return self.get_id() == other.get_id()
        return NotImplemented

    def __ne__(self, other):
        '''
        Checks the inequality of two `UserMixin` objects using `get_id`.
        '''
        equal = self.__eq__(other)
        if equal is NotImplemented:
            return NotImplemented
        return not equal

    if sys.version_info[0] != 2:  # pragma: no cover
        # Python 3 implicitly set __hash__ to None if we override __eq__
        # We set it back to its default implementation
        __hash__ = object.__hash__

但看了一下UserMixin类的源代码,有犯迷糊了。UserMixin类里面并没有定义构造函数__init__。那么实例是如何调用父类UserMixin的构造函数并继承父类的属性的?欢迎各位高手来解答!Thanks.

阅读 1.6k
1 个回答

MRO的查找方式是广度优先遍历,当UserMixin类中没有__init__时,查找的下一项就到了db.Model类,我猜这个类中应该有自定义的__init___方法

推荐问题