Python 具有长度的对象的类型
如何键入提示参数或Python 具有长度的对象的类型,python,types,Python,Types,如何键入提示参数或isinstance检查必须可编辑且可与len一起使用的对象?我假设几乎所有具有长度的对象都是iterable的,所以这实际上是关于什么类型(如果有的话)表示实现\uuu len\uuuu的对象 def n_and_list(x: ???): return len(x), [y for y in x] 它不是键入.Iterable或集合.Iterable,因为对于没有长度的事物,例如zip,这些都是正确的 In [1]: from typing import Iter
isinstance
检查必须可编辑且可与len
一起使用的对象?我假设几乎所有具有长度的对象都是iterable的,所以这实际上是关于什么类型(如果有的话)表示实现\uuu len\uuuu
的对象
def n_and_list(x: ???):
return len(x), [y for y in x]
它不是键入.Iterable
或集合.Iterable
,因为对于没有长度的事物,例如zip
,这些都是正确的
In [1]: from typing import Iterable
In [2]: isinstance(zip([]), Iterable)
Out[3]: True
In [3]: from collections import Iterable
In [4]: isinstance(zip([]), Iterable)
Out[4]: True
In [5]: len(zip([]))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-27-86d411a5426c> in <module>()
----> 1 len(zip([]))
TypeError: object of type 'zip' has no len()
它不是iterable
或iter
,因为它们不是类型。它不是列表
或元组
,因为它们太窄了。有这样的理由:
def n_and_list(x: collections.Sized):
return len(x), [y for y in x]
或者对于您的情况,因为您希望它具有\uuu len\uuuu
并可使用:
import typing
import collections
def n_and_list(x: typing.Union[collections.Sized, collections.Iterable]):
return len(x), [y for y in x]
遗憾的是,正如下面的评论所提到的,到目前为止,还没有
键入.Intersection
来保证两者的存在。您可以使用键入.Collection
,如果您没有将\uuuuuuuuu包含\uuuu
作为一项要求:
class Collection(Sized, Iterable, Container):
__slots__ = ()
@classmethod
def __subclasshook__(cls, C):
if cls is Collection:
return _check_methods(C, "__len__", "__iter__", "__contains__")
return NotImplemented
如果您这样做,只需删除对\uuuuuu包含的检查,大小可编辑的
就可以轻松实现
class SizedIterable(Sized, Iterable):
__slots__ = ()
@classmethod
def __subclasshook__(cls, C):
if cls is SizedIterable:
return _check_methods(C, "__len__", "__iter__")
return NotImplemented
这只会检查x
是否有\uu\uu\uu
方法。从技术上讲,可能存在一个x
,它具有\uu len\uuu
,但不可编辑。编辑:键入。Union
不能解决问题;这只会让事情变得更糟Union[Sized,Iterable]
检查x
是否为Sized或Iterable;它不要求x
两者都是。打字。Union
是“或”,而“大小
是我缺少的主要部分。为了同时具有大小
和可伸缩性
,我需要一个交集类型而不是并集类型。我不知道Python是否有这个功能。typing.size
也是collections.abc.size
的别名typing.Collection
继承了Sized
和Iterable
(和Container
,它断言存在\uuuuuuuuuuuuuuuuuuuuuuuuuuuu contains
)。交集
列在“我们可能添加”下。
class SizedIterable(Sized, Iterable):
__slots__ = ()
@classmethod
def __subclasshook__(cls, C):
if cls is SizedIterable:
return _check_methods(C, "__len__", "__iter__")
return NotImplemented