我正在为int,str,bool等编写自己的类。上面有发电机我使用它来模糊基于类型注解的函数。除了union类型的|
符号之外,这一切都很顺利。如果我输入类似这样的内容:
def test_handles_none_with_arged_types(
x: Int[0, 10] | List[Int] | Str | Dict[NoneType, List[NoneType]]
):
assert type(x) in [int, list, str, dict, list]
if type(x) == int:
assert x >= 0 and x <= 10
if type(x) == list:
assert all([el is None for el in x])
if type(x) == dict:
for k, v in x.items():
assert k is None
assert type(v) == list
for el in v:
assert el is None
Python给出了以下错误:
TypeError: unsupported operand type(s) for |: 'Int' and 'List'
这似乎是因为Int[0,10]
的类型是pybt.typing.Int
,而不是type
。但是,使用typing.Union
工作得很好。
def test_handles_none_with_arged_types(
x: Union[Int[0, 10], List[Int], Str, Dict[NoneType, List[NoneType]]]
):
...
有办法解决这个问题吗?不幸的是,我想不出一种方法来推迟示例化Int
或其他在__class_getitem__
下索引的类型。
编辑:
下面是完整的类(用于List):
class List:
def __init__(self, sub_type=_DEFAULT_SUB_TYPE, max_len=_DEFAULT_MAX_LEN):
self.max_len: int = _DEFAULT_MAX_LEN
self.sub_type = sub_type
if max_len is not None:
self.max_len = max_len
def __str__(self):
return "pybt.types.List"
def __class_getitem__(cls, parameters):
sub_type = None
max_len = None
if type(parameters) != tuple:
parameters = (parameters,)
if len(parameters) > 2:
raise TypeError("Expected 2 arguments: List[sub_type, max_length]")
if len(parameters):
sub_type = parameters[0]
if len(parameters) > 1:
max_len = parameters[1]
if max_len and max_len <= 0:
raise TypeError(f"Max Length of {cls.max_len} is less than or equal to 0")
return cls(sub_type, max_len)
1条答案
按热度按时间nwlls2ji1#
您已经知道dunder方法和
type
,因此,如果这个答案对您来说是显而易见的,请原谅。要使
Int() | List()
(或任何创建示例的东西,如List[]
)工作,必须有Int.__or__
或List.__ror__
,或两者都有。这适用于
Int | List
中的类,因为type
本身实现了__or__
和__ror__
:因此,尝试将以下方法添加到您的类中:
它似乎可以很好地与其他类型,甚至它自己的类: