如何使用@property设置器并使mypy满意?

9

我拥有以下的example.py文件:

class Location(object):
    def __init__(self, latitude, longitude):
        self.latitude = latitude
        self.longitude = longitude

    @property
    def latitude(self):
        return self._latitude

    @property
    def longitude(self):
        return self._longitude

    @latitude.setter
    def latitude(self, latitude):
        """Setter for latiutde."""
        if not (-90 <= latitude <= 90):
            raise ValueError('latitude was {}, but has to be in [-90, 90]'
                             .format(latitude))
        self._latitude = latitude

    @longitude.setter
    def longitude(self, longitude):
        """Setter for longitude."""
        if not (-180 <= longitude <= 180):
            raise ValueError('longitude was {}, but has to be in [-180, 180]'
                             .format(longitude))
        self._longitude = longitude

    def __repr__(self):
        return 'Location({}, {})'.format(self.latitude, self.longitude)

    __str__ = __repr__


munich = Location(48.137222222222, 11.57555)
print(munich)
try:
    munich.latitude = 200
    print("This should not work")
except ValueError:
    pass

当我运行mypy example.py(mypy版本0.73)时,我遇到了一些错误:

$ mypy example.py 
example.py:14: error: Name 'latitude' already defined on line 6
example.py:14: error: "Callable[[Any], Any]" has no attribute "setter"
example.py:22: error: Name 'longitude' already defined on line 10
example.py:22: error: "Callable[[Any], Any]" has no attribute "setter"
example.py:39: error: Property "latitude" defined in "Location" is read-only
Found 5 errors in 1 file (checked 1 source file)

为什么我会遇到这些问题,如何解决呢?

Mypy 可能不喜欢您传递与方法名称完全相同的参数: def longitude(self, longitude): - Error - Syntactical Remorse
https://github.com/python/mypy/issues/1465 是问题的来源 :-) - Martin Thoma
是的,我不知道他们的逻辑是什么,也不知道为什么他们不会修复它,但我猜这就是一个功能 :)。 - Error - Syntactical Remorse
你想把它发布为答案,还是我应该创建一个社区维基答案? :-) - Martin Thoma
1个回答

17

这个问题可能与属性设置器不被接受,如果不紧挨着getter则不被接受有关。

以下代码错误地引发错误:

class Config(object):

    @property
    def my_proprty(self):
        return None

    def _other(self):
        pass

    @my_proprty.setter
    def my_proprty(self, val):
        pass Error:
mypytest.py: note: In class "Config": mypytest.py:12: error:
Callable[[Any], Any] has no attribute "setter"

MyPy关闭了该问题并将其标记为误报。截至目前,他们似乎没有修复的意图。

我们暂时没有计划修复此问题,但很高兴收到PR。-JukkaL

将getter和setter移到一起(getter在前)应该可以解决这个问题。

认为它是一个特性 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接