iterables的公共基类?

2024-10-01 07:27:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图创建一个只接受iterable参数的方法,比如listtupleset或{}。在

我的代码是:

class MjmMenuControl(MjmBaseMenu):
    def __init__(self, items=None):
        iterables = (dict, list, set, tuple)
        for iterable in iterables:
            if isinstance(items, iterable):
                ...
                break

然而,我想知道是否有更简单的方法,比如if isinstance(items, <iterable_base_class>):,但是我什么都找不到。在

我已经尝试为list等查找基类,但它们似乎都是从object派生的:

^{pr2}$

这是可能的还是我必须坚持可怕的for循环?在


Tags: 方法代码for参数ifitemsiterablelist
2条回答

是,使用^{}

>>> from collections import abc
>>> isinstance(set(), abc.Iterable)
True
>>> isinstance((), abc.Iterable)
True
>>> isinstance([], abc.Iterable)
True
>>> isinstance('', abc.Iterable)
True
>>> isinstance({}, abc.Iterable)
True
>>> isinstance(0, abc.Iterable)
False

但是,我只需要让方法假设传递了一个iterable,调用者负责确保传入正确的类型。在

在python3.3中,^{} module是新的;它的内容以前放在^{} module中,尽管名称在python3.3及更高版本中仍然可用。在

collections.abc.Iterable选项的一个弱点是它不能处理像这样的自定义iterable类。。。在

from collections.abc import Iterable

class MyIterable(object):
    def __getitem__(self, index):
        if index >= 10:
            raise IndexError
        return index

>>> myiter = MyIterable()
>>> isinstance(myiter, Iterable)
False
>>> [i for i in myiter]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

经常有人说,Pythonic的方法是使用duck typing,即尝试将对象视为iterable,并在异常失败时处理异常。例如。。。在

^{pr2}$

…但是,这两种方法都有一个弱点,即将字符串视为与列表相同的东西,这通常不是您想要的。通常您希望测试iterable容器,这是略有不同的,因此通常会看到代码将字符串视为这种特殊情况。。。在

class MjmMenuControl(MjmBaseMenu):
    def __init__(self, items=None):
        if isinstance(items, (str, bytes)):
            do_something_else()
        else:
            try:
                for item in items:
                    do_something_with(item)
            except TypeError:
                # If we get here, 'items' is not iterable
                do_something_else()

…虽然有点乱,但能完成任务。在

相关问题 更多 >