我必须管理权限,并且我有不同的用户类型,例如举一对夫妇的例子。
def not_allowed(*args, **kwargs): return False
class User(object):
def __init__(self, userid):
self.userid = userid
def __getattr__(self, attr):
return not_allowed
def view_profile(self)
return True
class Admin(User):
def edit_comment(self):
return True
class Expert(User):
def delete_post(self):
return True
user = {'userid': 'user', 'roles': ['admin', 'expert']}
现在我想拥有MultiRole类型,理论上应该只需能够做其角色所能做的一切。
我试过这样的东西:
class MultiRoleUser(User):
"""A multirole user has all the power of all the roles together
"""
def __init__(self, userid, roles):
super(MultiRoleUser, self).__init__(userid)
self.roles = roles
def __getattr__(self, attr):
all_funcs = [getattr(x, attr) for x in self.roles]
return any(x() for x in all_funcs)
应该用作
u = MultiRoleUser('userid', [Admin, Expert])
但它不起作用,理想情况下,我想调用所有的方法传入的类执行a或(与任意类一起)。
问题是,要调用方法,我需要有一个那种。。
理论上,我甚至可以为每个角色使用一本字典,但我喜欢默认为假的把戏,有时我还需要一个函数来计算权限。
有什么建议吗?
尽管我倾向于同意你可能不想在这方面重新发明轮子,但下面是你的尝试的版本,它似乎可以在AFAIK中工作。
基本上,我首先必须切换到显式的新型类,使它们从object
派生,以便super()
调用能够工作,然后,我更改了MultiRoleUser
类中的self.roles = roles
初始化,以创建所需的实例。最后,我更改了MultiRoleUser.__getattr__()
如何使用它们来处理没有"搜索权限"属性的角色类。
def not_allowed(*args, **kwargs): return False
class User(object):
def __init__(self, userid):
self.userid = userid
def __getattr__(self, attr):
return not_allowed
def view_profile(self):
return True
class Admin(User):
def edit_comment(self):
return True
class Expert(User):
def delete_post(self):
return True
class MultiRoleUser(User):
"""A multirole user has all the power of all the roles together"""
def __init__(self, userid, roles):
super(MultiRoleUser, self).__init__(userid)
self.roles = [role(userid) for role in roles] # create instances needed
def __getattr__(self, attr):
all_funcs = [getattr(x, attr, None) for x in self.roles]
return any(x() for x in all_funcs if x) # check permission if there was one
u = MultiRoleUser('userid', [Admin, Expert])
print 'u.edit_comment:', u.edit_comment
print 'u.delete_post:', u.delete_post
顺便说一句,我认为更好的Python实现应该使用sets
及其操作来完成您想要做的事情
这里有一个替代答案,它使用多个继承和属性来大大简化实现(因为,再一次,您本质上是在重新发明轮子)。它完全消除了在MultiRoleUser
类中具有roles
属性的需要,以及使用它所需的专用getattr()
方法
我想到了使用多重继承的想法,因为将class MultiRoleUser
定义为具有多个User
子类实例的,而不仅仅是本身是一个,这似乎很奇怪。使用属性的想法源于这样一个事实,即类所需的gettattr()
类调用找到的函数属性以获取其值,这是属性的一部分。
class User(object):
def __init__(self, userid):
self.userid = userid
def __getattr__(self, attr): # unknown/undefined permission
return False
@property
def view_profile(self):
return True
class Admin(User):
@property
def edit_comment(self):
return True
class Expert(User):
@property
def delete_post(self):
return True
def multi_role_user(cls_name, *roles):
"""Factory function to create a multirole user class which has the combined
power of all the User subclasses given"""
if not roles:
raise TypeError('at least one subclass of class User must be specified')
if not all(issubclass(role, User) for role in roles):
raise TypeError('all roles must be subclasses of class User')
return type(cls_name, roles, {})
MultiRoleUser = multi_role_user('MultiRoleUser', Admin, Expert)
u = MultiRoleUser('my_userid')
print 'u.userid:', u.userid
print 'u.view_profile:', u.view_profile
print 'u.edit_comment:', u.edit_comment
print 'u.delete_post:', u.delete_post
print 'u.can_spam:', u.can_spam