我有几个自定义类,看起来像这样:
from typing import List
from typing_extensions import Self
class Page:
def __init__(self, search_id: str, page_num: int) -> None:
self.search_id = search_id
self.page_num = page_num
self.isLast = False
def mark_as_last(self):
self.isLast = True
class Pages:
def __new__(cls: Self, search_id: str, range_of_pages: List[int]):
instance = super(Pages, cls).__new__(cls)
return instance.pages
def __init__(self, search_id: str, range_of_pages: List[int]):
self.search_id = search_id
self.ranges_of_pages = range_of_pages
self.pages = Pages.create_pages(self.ranges_of_pages, self.search_id)
@staticmethod
def create_pages(range_of_pages: List[int], search_id: str) -> List[Page]:
pages = []
for page_num in range_of_pages:
page = Page(search_id, page_num)
if page_num == range_of_pages[-1]:
page.mark_as_last()
pages.append(page)
return pages
def __getitem__(self, item):
return self.pages[item]
当'Pages'像Pages('123', [1, 2, 3, 4])
一样被调用时,我想返回一个页面列表-参见return instance.pages
嗯…当我到达这一点时,我得到一个错误。特别是这个错误:
def __new__(cls: Self, search_id: str, range_of_pages: List[int]):
instance = super(Pages, cls).__new__(cls)
return instance.pages
E AttributeError: 'Pages' object has no attribute 'pages'
我错过了什么吗?这应该行得通。我不知道这里出了什么问题。
__new__
处理类实例的创建,而__init__
初始化它。由于__new__
在__init__
之前运行,因此创建的实例还没有__init__
中分配的pages
属性。
我不认为从__new__
返回一个与类不同类型的对象是一个好主意,但这是可能的(参见:类的构造函数可以在Python中返回另一个类吗?)。
在您的情况下,您试图访问并返回在__init__
中初始化之前新创建的Pages
对象的.pages
属性,在__new__
之后称为。
由于__new__
依赖于__init__
中当前发生的一切,因此您必须将所有内容移动到__new__
中。
class Pages:
def __new__(cls: Self, search_id: str, range_of_pages: List[int]):
instance = super(Pages, cls).__new__(cls)
instance.search_id = search_id
instance.ranges_of_pages = range_of_pages
return Pages.create_pages(ranges_of_pages, search_id)
但这真的让我想知道为什么需要这门课。search_id
和ranges_of_pages
属性似乎在其他任何地方都不需要(事实上它们不能,因为Pages
实例会立即被丢弃),所以您可以删除该类并使create_pages
成为一个自由函数。