python常量装饰器在应用于函数时不接受 self

jac*_*ton 1 python

我做了一个看起来像这样的常量装饰

def constant(f):
  def fset(self, value):
    raise TypeError
  @wraps(f)
  def fget(self):
    return f()
  return property(fget, fset)
Run Code Online (Sandbox Code Playgroud)

但是当我在函数上使用它并调用它时,由于没有传递足够的参数而引发类型错误,我认为添加包装装饰器可以解决这个问题,但事实并非如此。

class IrrigationAmount(AbstractCalculation):

    def __init__(self, wvf, fc):
        self._wvf = float(wvf)
        self._fc = float(fc)
        self._value = 0

    def calculate(self):
        self._value = (self.fc*SECTORVOLUME - self.wvf*SECTORVOLUME)/FLOWRATE

    @constant
    def value(self):
        return self._value
Run Code Online (Sandbox Code Playgroud)

这是我测试的方法,我不明白我做错了什么,主要是为什么 self 由于换行而没有被自动传递。我可能误解了wrapper 的作用。

    >>> from irrigationservice.irrigation import IrrigationAmount
>>> a = IrrigationAmount(0.12, 0.2)
>>> a.calculate()
>>> a.value
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/Users/krishna/Documents/irrigationwebserver/webserver/irrigationservice/utils.py", line 12, in fget
    return f()
TypeError: value() takes exactly 1 argument (0 given)
Run Code Online (Sandbox Code Playgroud)

Ste*_*uta 5

我认为你想用这样的东西替换常量函数定义和 @constant 装饰器:

@property
def value(self):
    """return the protected value"""
    return self._value
Run Code Online (Sandbox Code Playgroud)

编辑:添加以下示例来解决一些评论

创建文件 myvalue.py...

class MyValue:

    def __init__(self, x, y):
        self._x = x
        self._y = y
        self._value = 0

    def calculate(self):
        self._value = self._x*self._y

    @property
    def value(self):
        """return the protected value"""
        return self._value
Run Code Online (Sandbox Code Playgroud)

现在在Python中运行:

>>> from myvalue import MyValue
>>> z = MyValue(2, 3)
>>> z.value
0
>>> z.calculate()
>>> z.value
6
>>> z.value = 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)