python - 有没有更快的方法将 @property 用于类中的多个属性?

标签 python python-decorators

是否有比使用 @property 方法更短的方法来向类添加属性并验证设置?下面的代码是一个示例。我希望能够对类中的许多属性进行验证,这样做似乎是多余的。非常感谢任何建议!

def valid_max(max_val=10):
"""
Decorator to check for valid value of a number between min and max

"""
def valid_value_decorator(func):
    def func_wrapper(wraps,value):
        if value <= max_val:
            return func(wraps,value)
        else:
            raise(Exception('Value above max'))
    return func_wrapper
return valid_value_decorator

class Test(object):
    def __init__(self):
        self._x=0
        self._y=0

    @property
    def x(self):
        return self._x

    @x.setter
    @valid_max(max_val=10)
    def x(self,data):
       self._x = data

    @property
    def y(self):
        return self._y

    @y.setter
    @valid_max(max_val=10)
    def y(self,data):
        self._y = data

最佳答案

你可以写一个 factory function生成属性:

def CustomProp(name, maxval):
    name = '_' + name

    @property
    def pro(self):
        return getattr(self, name)

    @pro.setter
    def pro(self, val):
        if not isinstance(val, (int, float)):
            # In Python 2 -> '' > 10(or any number) is True, so better check the type as well.
            raise TypeError('Only integers and floats are allowed.')
        if val > maxval:
            raise ValueError("Value {!r} above maximum {!r}.".format(val, maxval))
        else:
            setattr(self, name, val)

    return pro

class Test(object):
    x = CustomProp('x', 10)
    y = CustomProp('y', 20)
    z = CustomProp('z', 30)

    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

演示:

>>> t = Test(1, 2, 3)
>>> t.x = 10
>>> t.y = 11
>>> t.x = 11

Traceback (most recent call last):
  File "<pyshell#41>", line 1, in <module>
    t.x = 11
  File "/home/ashwini/py/so.py", line 14, in pro
    raise ValueError("Value {!r} above maximum {!r}.".format(val, maxval))
ValueError: Value 11 above maximum 10.
>>> t.x = 'Python'

Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    t.x = 'Python'
  File "/home/ashwini/py/so.py", line 12, in pro
    raise TypeError('Only integers and floats are allowed.')
TypeError: Only integers and floats are allowed.
>>> t.z = 31

Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    t.z = 31
  File "/home/ashwini/py/so.py", line 14, in pro
    raise ValueError("Value {!r} above maximum {!r}.".format(val, maxval))
ValueError: Value 31 above maximum 30.
>>> t.x, t.y, t.z
(10, 11, 3)

关于python - 有没有更快的方法将 @property 用于类中的多个属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27949403/

相关文章:

python flask API模块如何将动态参数传递给装饰器

python - 一个函数有两个装饰器,后一个函数没有按预期工作?

python - 将装饰器应用于 __init__ 函数是pythonic吗?

python - 具有 3d 输入的 Pytorch 交叉熵损失

python - 神经网络的数据准备(列为输入和输出)。需要推荐

python - 如何检查Python中的函数装饰器

python - 使用 python 装饰器缩放翻译函数

javascript - 从 ASX 页面抓取表格

python - 如何检查 selenium (python 2) 中是否存在某个元素,如果不存在则不抛出 NoSuchElement 异常?

Python IRC Bot 在某些服务器上不会加入 channel ,我不知道如何让它响应用户输入