如何在Python中通过__iter__和__next__从另一类访问私有字典
如何通过__iter__和__next__访问父类的私有字典
原代码存在两个核心问题:
- 字典无法通过整数索引
self.__products[self.__index]访问,这会直接触发KeyError - 当前
__next__方法仅尝试返回字典的值,没有获取键的逻辑
我们可以通过将字典的键(或键值对)转换为可索引的列表,在迭代器中遍历这个列表,让子类能通过迭代获取私有字典的内容,以下是两种可行方案:
方案1:迭代返回Product对象(字典的键)
修改Store类的迭代器方法,让它遍历字典的键,子类迭代时直接拿到Product对象:
class Store(AbstractStore, Displayable): def __init__(self, store_name: str) -> None: self.__store_name = store_name self.__products: dict[Product, int] = {} # Product是对象,int是对应数量 def __iter__(self): # 将字典的键转换为列表,方便按索引遍历 self.__product_keys = list(self.__products.keys()) self.__index = -1 return self def __next__(self) -> Product: self.__index += 1 if self.__index >= len(self.__product_keys): raise StopIteration() # 返回对应的Product对象(字典的键) return self.__product_keys[self.__index] class Bookstore(Store): def get_products_high_price(self, limit: float) -> list[Product]: products: list[Product] = [] for product in self: # 迭代得到的是Product对象 if product.price > limit: # 假设Product类有price属性 products.append(product) return products
方案2:迭代返回键值对(Product和对应数量)
如果子类需要同时获取产品和库存数量,可以让迭代器返回元组:
class Store(AbstractStore, Displayable): def __init__(self, store_name: str) -> None: self.__store_name = store_name self.__products: dict[Product, int] = {} def __iter__(self): # 将字典的键值对转换为列表 self.__product_items = list(self.__products.items()) self.__index = -1 return self def __next__(self) -> tuple[Product, int]: self.__index += 1 if self.__index >= len(self.__product_items): raise StopIteration() # 返回(Product对象, 数量)的元组 return self.__product_items[self.__index] class Bookstore(Store): def get_products_high_price(self, limit: float) -> list[Product]: products: list[Product] = [] for product, count in self: # 同时获取产品和数量 if product.price > limit: products.append(product) return products
关键说明
- 父类的私有属性
__products虽然不能被子类直接访问,但父类可以通过迭代器接口暴露内部数据,这是符合封装原则的合理做法。 - 原代码中用整数索引访问字典是错误的,因为字典的索引是键(这里是Product对象)而非整数,必须先将字典的键或键值对转换为列表,才能按索引遍历。
内容的提问来源于stack exchange,提问作者Anika Zaira
相关产品推荐
相关产品推荐

