Python - 使类装饰器在派生类上工作

标签 python oop decorator

在我们使用 Django 开发的应用程序中,在某些情况下,我们需要自动为某些模型的用户分配权限,这些模型具有所有者(字段名称没有规则,可以是“用户”、“所有者” ,“教练”等,也可以有多个字段。)我的解决方案是创建一个包含这些字段名称的装饰器,它将放在模型定义之前,就像这样(不在示例中使用特定于 django 的代码):

@auto_assign_perms('owner', 'user')
class Test(Base):
    pass

假设 Base 是派生自 Django 的 Model 类的抽象类,我在其中添加了在保存对象后分配权限的功能。现在我只打印分配给类(class)的用户列表。您可以在下面找到装饰器和 Base 类的代码:

class auto_assign_perms(object):
    def __init__(self, *users):
        self.users = users

    def __call__(self, cls):
        cls.owners.update(self.users)
        return cls


class Base(object):
    owners = set()

    def save(self, *args, **kwargs):
        for owner in self.owners:
            print owner,
        print

我的模型看起来像这样:

@auto_assign_perms('owner', 'user')
class Test(Base):
    pass

@auto_assign_perms('coach')
class Test2(Base):
    pass

问题是两个子类都包含所有三个字段('owner', 'user', 'coach'),虽然print self.__class__.__name__ Base.save() 方法正确显示“Test”或“Test2”。我尝试在 Base 类中添加类方法 get_owners(),然后迭代其结果,但没有帮助。 我该如何解决这个问题?也许我应该使用元类(我还没有得到)?提前致谢。

最佳答案

您需要设置所有者列表,而不是更新:

class auto_assign_perms(object):
    def __init__(self, *users):
        self.users = users

    def __call__(self, cls):
        cls.owners = set(self.users) # <- here
        return cls

#some tests
@auto_assign_perms('owner', 'user')
class Test(Base):
    pass

@auto_assign_perms('coach')
class Test2(Base):
    pass


t = Test()
t.save()
t = Test2()
t.save()

>>> 
owner user
coach

关于Python - 使类装饰器在派生类上工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6383613/

相关文章:

python - 使用 SQLAlchemy 将行从一个表批量移动到另一个表

python - tensorflow 除以 0/0= :0

python - 无法使用 Facebook Marketing API 获取暂停的广告见解

ruby-on-rails - Rails 模型中是否可以自动返回虚拟属性?

python - 使用 isin() 来确定应该打印什么

c++ - 如何对 Singleton 类进行单元测试 - C++?

java - 类 : what's the best practice? 中的条件恒定属性

java - 当我将某些类变量重新分配给新对象时会发生什么?

c++ - 这是解决 mixins 构造函数问题的有效解决方法吗?

装饰器模式,Head First 设计模式