如何使用 mypy 和 @属性 赋值?
How can I assign values with mypy and @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")
在你的例子中可能有错字,而不是
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"""
使错误消失。
顺便说一句,用 abstractmethod
装饰 ListNode.next
setter 会导致错误
> 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
删除 setter 会导致
> 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不满意说“未解决的引用'Optional'”,但似乎对 mypy 没问题)。
我正在使用 @属性 装饰器并为它赋值 属性。但是,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")
在你的例子中可能有错字,而不是
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
@next.setter
def next(self, next_):
"""Write the next attribute"""
使错误消失。
顺便说一句,用 abstractmethod
装饰 ListNode.next
setter 会导致错误
> 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
删除 setter 会导致
> 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不满意说“未解决的引用'Optional'”,但似乎对 mypy 没问题)。