有可能找出一个类的实例是否有__dict__?

时间:2018-02-14 14:15:29

标签: python python-3.x

如果输入任意类X,是否可以找出X的实例是否会有__dict__

我尝试了hasattr(X, '__dict__'),但这不起作用,因为它会检查类对象是否有__dict__

>>> hasattr(int, '__dict__')
True
>>> vars(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute

缺少__slots__也不能保证__dict__

>>> hasattr(int, '__slots__')
False
>>> vars(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute

我还考虑使用X创建object.__new__(X)的实例(绕过X.__new__X.__init__,这可能会产生意外的副作用),但这对构建失败了-in类型:

>>> hasattr(object.__new__(int), '__dict__')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object.__new__(int) is not safe, use int.__new__()

是否可以在不调用任何未知/不受信任的代码(如X的构造函数)的情况下执行此操作?

2 个答案:

答案 0 :(得分:1)

dir()将在Python3中列出__dict__,例如:

>>> class MyInt(int):
...     pass
...
>>> '__dict__' in dir(int)
False
>>> '__dict__' in dir(MyInt)
True
>>>

答案 1 :(得分:1)

您可以使用inspect模块获取非方法

的实例的所有属性
>>> import inspect
>>> from operator import itemgetter

>>> b = 5
>>> inspect.getmembers(b, lambda a:not(inspect.isroutine(a)))

将生成b所有属性及其小描述的长列表。

我已经进行了一些测试,看看它是如何工作的,以下是我的发现

>>> def get_attrs(x):
       return list(map(itemgetter(0), inspect.getmembers(x, lambda a:not(inspect.isroutine(a)))))

>>> "__dict__" in get_attrs(type(b))
>>> False

>>> l = [1,2,3]
>>> "__dict__" in get_attr(type(l))
>>> False

>>> class A:
       pass

>>> a = A()
>>> "__dict__" in get_attr(type(a))
>>> True