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