提问人:Itay Dvash 提问时间:5/8/2023 最后编辑:Itay Dvash 更新时间:5/8/2023 访问量:814
TypeError:“property”类型的对象没有 len()
TypeError: object of type 'property' has no len()
问:
我有一个包含自定义对象列表的类的代码。对于此列表,我创建了一个属性以允许访问它:_offers
Offer
class OffersManager:
_offers: list[Offer] = []
@property
def offers(cls) -> list[Offer]:
return cls._offers
问题是程序将此列表视为“属性”对象,因此当我尝试获取列表的长度时,它给了我一个错误:
>>> len(OffersManager.offers)
>>> Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
len(OffersManager.offers)
TypeError: object of type 'property' has no len()
有人可以告诉我使属性以列表形式返回属性的正确方法吗?
答:
2赞
yut23
5/8/2023
#1
从评论中更新:这已被弃用,可能无法正常工作,请改用 SUTerliakov 答案中的元类方法。
您需要将属性标记为类方法,以便它绑定到类本身而不是实例:
class OffersManager:
_offers: list[OfferData] = []
@classmethod
@property
def offers(cls) -> list[OfferData]:
return cls._offers
评论
0赞
Itay Dvash
5/8/2023
非常感谢!我会向那些将来会遇到这个问题的人强调,装饰器的顺序很重要(我试图反转它们并得到同样的错误)。
2赞
chepner
5/8/2023
不建议这样做;允许您定义“类”属性的机制已弃用;文档表明它已从 Python 3.11 中删除(尽管它似乎仍然可以在该版本中工作)。
0赞
yut23
5/8/2023
有趣的是,我不知道!为了将来参考,请参阅 Python 3.11 发行说明条目。
1赞
STerliakov
5/8/2023
#2
为了避免过去从未正常工作过的已弃用功能,可以在元类上定义属性:
from __future__ import annotations
from typing import TypeAlias
OfferData: TypeAlias = int
class OffersManagerMeta(type):
_offers: list[OfferData] = []
@property
def offers(cls) -> list[OfferData]:
return cls._offers
class OffersManager(metaclass=OffersManagerMeta):
pass
print(OffersManager.offers)
OffersManager._offers = [1, 2]
print(OffersManager.offers)
这甚至通过了严格的.mypy
评论
0赞
Bartek Lachowicz
9/5/2023
真正的问题:为什么在 OffersManagerMeta 中使用 inherit from type?
上一个:创建对象的更简洁方式
评论
offers
OffersManager