代码之家  ›  专栏  ›  技术社区  ›  Rovanion

是否有一个python类型签名匹配列表、dict和set,但不匹配字符串?

  •  2
  • Rovanion  · 技术社区  · 7 年前

    假设您有一个在python数据结构中内置的读入python的任意json对象。假设您希望递归地遍历此结构并对所有原语值执行某些操作,并在集合上进行更深入的递归。

    def recursiveMap(something, func):
      if isinstance(something, Collection):
        for item in something:
          return recursiveMap(item, func)
      else:
        return func(something)
    

    所以我的问题是:是否有一个类型集合可以匹配列表和字典,但不能匹配字符串?

    我的类型来源于 https://docs.python.org/3.6/library/collections.abc.html#collections-abstract-base-classes 我还没找到:

    >>> isinstance("", c.Container)
    True
    >>> isinstance("", c.Hashable)
    True
    >>> isinstance("", c.Iterable)
    True
    >>> isinstance("", c.Sized)
    True
    >>> isinstance("", c.Callable)
    False
    >>> isinstance({}, c.Callable)
    False
    >>> isinstance("", c.Sequence)
    True
    

    这不是关于python将字符串视为上述任何类型是否正确的问题,而是关于是否存在满足第一个代码列表中示例算法需要的其他类型的实际问题。

    2 回复  |  直到 7 年前
        1
  •  5
  •   Duncan    7 年前

    处理这一问题的每一种方法都是将要匹配的所有类型组合在一起。 isinstance 将采用类型的元组和单个类型:

    >>> CollectionTypes = list, dict, set
    >>> isinstance("", CollectionTypes)
    False
    >>> isinstance({}, CollectionTypes)
    True
    >>>
    

    如果确实找到与这三种类型完全匹配且不匹配的预定义类型 str 然后你把自己锁在里面,当你决定以后你也需要 tuple 或者其他一些类型将包括在比赛中,你将回到原点。这就是为什么最好在这里明确说明您要匹配的类型。

        2
  •  2
  •   Chris_Rands    7 年前

    因为您正在处理哈希(String)与非哈希(列表、DICT、SET)对象,所以可以使用 collections.Hashable :

    >>> import collections
    >>> isinstance([], collections.Hashable)
    False
    >>> isinstance({}, collections.Hashable)
    False
    >>> isinstance(set(), collections.Hashable)
    False
    >>> isinstance('', collections.Hashable)
    True
    

    当然要加 not 去扭转这一切。

    另一种方法是提供多个参数:

    >>> isinstance('', (set, dict, list))
    False
    >>> isinstance([], (set, dict, list))
    True