如何使用mypy和@property分配值?

问题描述 投票:1回答:1

我正在使用@property装饰器,并为该属性分配了一个值。但是,mypy对我的代码抛出错误(有效)。我做错什么了吗?如何修复我的代码,使mypy不会抱怨?

MVCE

# Core Library
from abc import ABCMeta, abstractmethod


class ListNode(metaclass=ABCMeta):
    def __init__(self, value):
        """Every list node should have a value at initialization."""

    @property
    @abstractmethod
    def value(self):
        """Read the value attribute"""

    @abstractmethod
    def next(self):
        """Read the next attribute"""


class SinglyLinkedListNode(ListNode):
    def __init__(self, value):
        self.value = value
        self.next = None  # Optional[SinglyLinkedListNode]

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = value

    @property
    def next(self):
        return self._next

    @next.setter
    def next(self, next_):
        self._next = next_


def reverse(list_node: ListNode) -> ListNode:
    """Reverse a list."""
    current = list_node
    previous = None

    while current is not None:
        previous, current.next, current = current, previous, current.next  # This throws the error

    return previous

错误:

mpu/datastructures/lists.py:47: error: Cannot assign to a method
mpu/datastructures/lists.py:47: error: Incompatible types in assignment (expression has type "ListNode", variable has type "Callable[[], Any]")
mpu/datastructures/lists.py:47: error: Incompatible types in assignment (expression has type "Callable[[], Any]", variable has type "ListNode")
python properties mypy
1个回答
0
投票

在您的示例中,可能是错字,而不是

self.next = None

应该是

self._next = None

因为我们用您的代码覆盖property的字段,似乎可以正常工作,但可能不希望这样做。

而且似乎ListNode.next也应该是property

class ListNode(metaclass=ABCMeta):
    ...

    @property
    @abstractmethod
    def next(self):
        """Read the next attribute"""

最后为ListNode.next添加setter

    @next.setter
    def next(self, next_):
        """Write the next attribute"""

使错误消失。


BTW用ListNode.next装饰abstractmethod设置程序会导致错误

> mypy test.py
test.py:14: error: Overloaded method has both abstract and non-abstract variants
test.py:19: error: Decorated property not supported
test.py:53: error: Property "next" defined in "ListNode" is read-only

并且似乎是多余的,因为删除SinglyLinkedListNode.next的二传手会导致

> mypy test.py
test.py:37: error: Read-only property cannot override read-write property

同样要使type comment正常工作,我们需要添加type:前缀

class SinglyLinkedListNode(ListNode):
    def __init__(self, value):
        self.value = value
        self._next = None  # type: Optional[SinglyLinkedListNode]

((我们也可以添加from typing import Optional,因为PyCharm对“ Unresolved reference'Optional'

不满意,但mypy似乎没问题)。
© www.soinside.com 2019 - 2024. All rights reserved.