简体   繁体   中英

Different results for `isinstance` with `collecitons.abc.Collection` and `collections.abc.Mapping`

I am having trouble understanding how isinstance is meant to work with the Abstract Base Classes from collections.abc . My class that implements all specified methods for collections.abc.Mapping does not make isinstance return True for my class, but does make isinstance return True for collections.abc.Collection . My class is not registered as a subclass with either ABC.

Running the following code (with Python 3.7, but I'm not sure if that matters):

class dictroproxy:
    def __init__(self, d): 
        self._d = d 
    def __getitem__(self, key):
        return self._d.__getitem__(key)
    def __contains__(self, key):
        return self._d.__contains__(key)
    def __len__(self):
        return self._d.__len__()
    def __iter__(self):
        return self._d.__iter__()
    def __eq__(self, other):
        if isinstance(other, dictroproxy):
            other = other._d
        return self._d.__eq__(other)
    def __ne__(self, other):
        return not self.__eq__(other)
    def get(self, key, default=None):
        return self._d.get(key, default)
    def keys(self):
        return self._d.keys()
    def values(self):
        return self._d.values()
    def items(self):
        return self._d.items()

if __name__ == "__main__":
    from collections.abc import Collection, Mapping
    dd = dictroproxy({"a": 1, "b": 2, "c": 3})
    print("Is collection?", isinstance(dd, Collection))
    print("Is mapping?", isinstance(dd, Mapping))

Gives me the following output:

Is collection? True
Is mapping? False

Am I missing something in my implementation, or do Collection and Mapping behave differently?

From my investigation into this I found that some ABCs implement a __subclasshook__ method to determine if a class seems like a subclass of the ABC. At least as of Python 3.9, some ABCs implement __subclasshook__ and some do not. Collection does and Mapping does not.

I haven't seen which ABCs this works for documented anywhere, so it may be that the only way to know is to try or review the source code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM