Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 具有长度的对象的类型_Python_Types - Fatal编程技术网

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