【发布时间】:2022-11-16 03:15:30
【问题描述】:
你能帮我理解为什么我在下面的代码中收到 TypeError: 'type' object is not subscriptable 错误吗?
也许我弄错了,但据我所知,filter() 函数中的 Color 类型注释表示该函数将导致 Iterable 为 Color ,这正是我想要的。但是当我尝试注释该函数时,我得到了错误。 (但是 waty,类型注释怎么会阻止程序运行?我认为 Python 中的类型提示只会在你的 IDE 中起作用,而不是在运行时)。
对此有任何了解将不胜感激。
# -*- coding: utf-8 -*-
from __future__ import annotations
from typing import TypeVar, Any, Generic, Iterator, Iterable
from abc import ABC, abstractmethod
from dataclasses import dataclass
T = TypeVar('T', bound=Any)
I = TypeVar('I', bound=Any)
class AbstractGenerator(ABC, Iterator[T], Generic[T, I]):
def __init__(self):
super().__init__()
self._items = None
self._next_item = None
@property
def items(self) -> Any:
return self._items
@items.setter
def items(self, items: Any) -> AbstractGenerator:
self._items = items
return self
@property
def next_item(self) -> Any:
return self._next_item
@next_item.setter
def next_item(self, next_item: Any) -> AbstractGenerator:
self._next_item = next_item
return self
@abstractmethod
def __len__(self) -> int:
pass
@abstractmethod
def __iter__(self) -> Iterable[T]:
pass
@abstractmethod
def __next__(self) -> Iterable[T]:
pass
@abstractmethod
def __getitem__(self, id: I) -> Iterable[T]:
pass
ColorId = int
@dataclass(frozen=True)
class Color:
id: ColorId
name: str
class MyColorsGenerator(AbstractGenerator[Color, int]):
def __init__(self):
super().__init__()
self._colors: list[Color] = []
self._next_color_index: int = 0 #None
@property
def colors(self) -> list[Color]:
return self._colors
@colors.setter
def colors(self, colors: list[Color]) -> MyColorsGenerator:
self._colors = colors
return self
@property
def next_color_index(self) -> int:
return self._next_color_index
@next_color_index.setter
def next_color_index(self, next_color_index: int) -> MyColorsGenerator:
self._next_color_index = next_color_index
return self
def add_color(self, color: Color) -> MyColorsGenerator:
self.colors.append(color)
return self
def __len__(self) -> int:
return len(self.colors)
def __iter__(self) -> Iterable[Color]:
return self
def __next__(self) -> Iterable[Color]:
if self.next_color_index < len(self.colors):
self.next_color_index += 1
return self.colors[self.next_color_index - 1]
else:
raise StopIteration
def __getitem__(self, id: ColorId) -> Iterable[Color]:
return list(filter[Color](lambda color: color.id == id, self.colors))
colors_generator: MyColorsGenerator = MyColorsGenerator()
colors_generator \
.add_color(Color(id=0, name="Blue")) \
.add_color(Color(id=1, name="Red")) \
.add_color(Color(id=2, name="Yellow")) \
.add_color(Color(id=3, name="Green")) \
.add_color(Color(id=4, name="White")) \
.add_color(Color(id=5, name="Black"))
# This results in: TypeError: 'type' object is not subscriptable
#colors: Optional[list[Color]] = list(filter[Color](lambda color: color.id == 4, colors_generator))
# This works, notice the only thing I did was to remove the type annotation for the expected generic type ([Color])
colors: Optional[list[Color]] = list(filter(lambda color: color.id == 4, colors_generator))
print(colors)
【问题讨论】:
标签: python types iterator generator