首页 > 解决方案 > python3列表过滤器lambda获取TypeError:'wrapper_descriptor'对象不可下标

问题描述

以下代码在 python2 中有效,但在 python3 中无效。我需要一些帮助,谢谢。

class A:
    a = (0, "a")
    b = (1, "b")

choice = 1

hit = len(list(filter(lambda x: getattr(A, x) is not None and getattr(A, x)[0]==choice, dir(A))))>0
print(hit)

在蟒蛇 2

$ python2 --version
Python 2.7.16
$ python2 b.py 
True

但是在python3

$ python3 --version
Python 3.9.0
$ python3 b.py
Traceback (most recent call last):
  File "/private/tmp/a/b.py", line 7, in <module>
    hit = len(list(filter(lambda x: getattr(A, x) is not None and getattr(A, x)[0]==choice, dir(A))))>0
  File "/private/tmp/a/b.py", line 7, in <lambda>
    hit = len(list(filter(lambda x: getattr(A, x) is not None and getattr(A, x)[0]==choice, dir(A))))>0
TypeError: 'wrapper_descriptor' object is not subscriptable

标签: python

解决方案


您看到 Python 2 和 Python 3 之间存在差异的原因是,在 Python 3 中,类隐式继承了object该类。在 Python 2 中,您有:

>>> dir(A)
['__doc__', '__module__', 'a', 'b']
>>> 

在这种情况下,两者都__doc__具有__module__value None,因此您的过滤器测试有效。

但在 Python 3 中,您也拥有object该类的所有内容:

>>> dir(A)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']
>>> 

其中一些属性既不是None也不是可下标的。例如,__class__属性是一种类型,并且不可下标,这可能是您的错误的来源。

理想情况下,您将使用已知的属性列表,而不依赖于dir(),但如果您想检查所有内容,您可以执行一些操作,例如忽略以 . 开头的属性__。那可以代替is not None测试。例如,以下代码适用于 Python 2 和 Python 3:

hit = len(list(filter(lambda x: not x.startswith("__") and getattr(A, x)[0]==choice, dir(A))))>0

推荐阅读