Python 创建类级装饰器以自动添加属性

Python 创建类级装饰器以自动添加属性,python,python-2.7,python-3.x,properties,python-decorators,Python,Python 2.7,Python 3.x,Properties,Python Decorators,我想创建一个类级装饰器,它自动向对象添加属性,包括适当的getter和setter方法以及一个支持变量。例如: @autoproperty("foo", can_get=True, can_set=True, allow_null=False, default_value=0) @autoproperty("baz", can_get=True, can_set=False, allow_null=True, default_value=0) @autoproperty("bar") class

我想创建一个类级装饰器,它自动向对象添加属性,包括适当的getter和setter方法以及一个支持变量。例如:

@autoproperty("foo", can_get=True, can_set=True, allow_null=False, default_value=0)
@autoproperty("baz", can_get=True, can_set=False, allow_null=True, default_value=0)
@autoproperty("bar")
class SomeNonTrivialClass(object):
   def __init__(self):
      #lots of stuff going on here

   def discombobulate(self):
      #this is obviously a very trivial example
      local_foo = self.foo;

      if (local_foo > 10):
         raise RuntimeError("Foo can never be more than 10")
      else:
         #do whatever with foo

if __name__ == '__main__':
   test = SomeNonTrivialClass()

   test.foo = 5
   test.discombobulate()
   test.foo = 11
   test.discombobulate()
我经常发现自己创建了很多“半复杂”的getter/setter(它们可以用一个简单的属性来完成,但是它们需要默认值和空保护。我希望能够指定一个decorator来完成在类的新实例上创建属性的繁重工作

class SomeNonTrivialClass(object):
   def __init__(self):
      #lots of stuff going on here

   foo = autoproperty("foo", can_get=True, can_set=True, allow_null=False, default_value=0)

   def discombobulate(self):
      #this is obviously a very trivial example
      local_foo = self.foo;

class autoproperty(property):
    def __init__(self, name, can_get, can_set, allow_null, default_value):
        ...
如果我在这种方法上偏离了基础,我会接受一种同样可行的方法

任何帮助都将不胜感激

我正在使用Python3.X和Python2.7,因此最好使用在这两种语言中都能工作的东西,但这不是必需的


更新:我在寻找的内容中添加了更多种类。一般来说,我需要能够创建许多这些简单的自动属性(ala C#auto属性,但具有更大的灵活性)。我不一定要公开备份存储,但我确实希望确保对实例化对象的检查(不一定是类)显示已创建的属性。

这里有一种更直接的方法,可以避免装饰类

class SomeNonTrivialClass(object):
   def __init__(self):
      #lots of stuff going on here

   foo = autoproperty("foo", can_get=True, can_set=True, allow_null=False, default_value=0)

   def discombobulate(self):
      #this is obviously a very trivial example
      local_foo = self.foo;

class autoproperty(property):
    def __init__(self, name, can_get, can_set, allow_null, default_value):
        ...

下面的类装饰器将执行此操作:

def autoproperty(name, can_get=True, can_set=True, allow_null=False, default_value=0):
    attribute_name = '_' + name
    def getter(self):
        return getattr(self, attribute_name, default_value)
    def setter(self, value):
        if not allow_null and value is None:
            raise ValueError('Cannot set {} to None'.format(name))
        setattr(self, attribute_name, value)

    prop = property(getter if can_get else None, setter if can_set else None)

    def decorator(cls):
        setattr(cls, name, prop)
        return cls

    return decorator
但您也可以创建一个属性工厂:

def autoproperty(attribute_name, can_get=True, can_set=True, allow_null=False, default_value=0):
    def getter(self):
        return getattr(self, attribute_name, default_value)
    def setter(self, value):
        if not allow_null and value is None:
            raise ValueError('Cannot set {} to None'.format(name))
        setattr(self, attribute_name, value)
    return property(getter if can_get else None, setter if can_set else None)
然后在课堂上设置:

class SomeNonTrivialClass(object):
    # ...

    foo = autoproperty('_foo', can_get=True, can_set=True, allow_null=False, default_value=0)

如果您需要创建多个属性(可能具有相互依赖性),则类装饰器将更有意义。

我觉得这似乎是一个名称错误(因为在尝试创建类时未定义自动属性)。否则,据我所知,这是一个很好的建议…@mgilson:如果在两个类的主体之后创建实例,则无名称错误。我需要装饰该类的部分原因是,我在设计时不一定知道需要哪些属性。它们是从原型工厂设施创建的,之后会在那里添加自动属性。这是真的吗像你这样的人可能想写一些。你的问题是什么?@Robᵩ 我的问题是如何创建一个类级修饰符,该修饰符将在实例化时自动在类上创建正确的属性。@Eevee,我对python相当陌生,我可以创建描述符本身,但我很难弄清楚如何将其连接起来,以便当我创建一个类的新实例时,我可以使用该装备使用该属性ht约束在创建的实例上,不一定在类上。这正是我需要做的,我有一个类,它可能有十几个属性需要在其上配置。