字段的python装饰器

标签 python design-patterns decorator

我知道没有这样的事情。这就是为什么我正在寻找一些不错的等价物。有这个类:

class MyClass:
   a = 5
   b  = "foo"
   c = False

我想将字段 a 和 b 组合在一起,以便能够以某种方式仅迭代来自该组的成员。所以最好有某种字段装饰器,比如:

class MyClass:
   @bar
   a = 5
   @bar
   b  = "foo"
   c = False

还有一些像 myDir(MyClass, 'bar') 这样的函数会返回 ('a', 'b')。

到目前为止我们有哪些选择? 1. 按照特殊约定命名这些字段,例如“a_bar”、“b_bar”——但不幸的是我不能这样做。 2. 将姓名列表作为另一个类(class)成员——我想让这个分组属性接近属性,所以我不喜欢这种方法。 3. 我可以创建继承自整数和字符串的类,并添加另一个基类(如“Group”),然后检查类型,而不是将 5 分配给“a”和“foo”——这样我将不得不生成此类每次我都有新的类型,所以我也不喜欢这个解决方案。

还有其他想法吗?

最佳答案

装饰器只是函数调用的语法糖,所以要将装饰器应用于属性,您只需在初始化器上调用它:

a = bar(5)

在您的情况下,您可以创建实现描述符协议(protocol)的对象:

class GroupedAttribute(object):
    def __init__(self, group, obj):
        self.group = group
        self.obj = obj
    def __get__(self, obj, owner):
        return self.obj
    def __set__(self, obj, value):
        self.obj = value

为了优雅,您可以为属性组编写一个类:

class GroupedAttribute(object):
    def __init__(self, group, obj):
        self.group = group
        self.obj = obj
    def __get__(self, obj, owner):
        return self.obj
    def __set__(self, obj, value):
        self.obj = value

class AttributeGroup(object):
    def __call__(self, obj):
        return GroupedAttribute(self, obj)
    def __get__(self, obj, owner):
        return BoundAttributeGroup(self, obj, owner)

class BoundAttributeGroup(object):
    def __init__(self, group, obj, owner):
        self.group = group
        self.obj = obj
        self.owner = owner
    def __dir__(self):
        items = dir(self.owner if self.obj is None else self.obj)
        return [item for item in items if
                getattr(self.owner.__dict__.get(item, None),
                        'group', None) is self.group]

用法:

class MyClass(object):
    bar = AttributeGroup()
    a = bar(5)
    b = bar("foo")
    c = False
dir(MyClass.bar)    # ['a', 'b']

关于字段的python装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13532780/

相关文章:

Python 合并列-行中的值(单元格类型为列表)

go - 应用程序设计 : Central vs Private cache

python - 我可以在 Python 中将两个装饰器组合成一个吗?

javascript - 装饰器不会向它正在装饰的类添加属性。我如何解决它?

python - 从字符串Python中删除多个子字符串

python - 为什么我收到错误 - 在格式字符串中遇到单个 '}'

c# - 这种聚合设计模式有名称吗?

python - Try-finally 装饰器清理 python 对象

python - 按顺序生成所有可能的子串

php oop MVC 设计 - 应用程序编辑数据的适当架构