0

考虑一下:

>>> import math
>>> dir(math)
['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'hypot', 'isinf', 'isnan', 'ldexp', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

__dict__未列出,但我仍然可以

>>> math.__dict__

同样的事情

>>> class MyClass(object):
         def __init__(self, var1, var2):

             self.a = var1
             self.b = var2

         def __call__(self, arg):

             print " The arg passed is ", arg

>>> dir(MyClass) 

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

__bases____base__没有列出,但我仍然可以这样做:

>>> MyClass.__bases__
(<type 'object'>,)
>>> MyClass.__base__
<type 'object'>

问题:

我怎样才能知道或提前知道从 python 对象可以访问的所有属性?在这种情况下,我如何判断该math模块 has__dict__MyClasshas __base__and __bases__

4

1 回答 1

2

如果您正在寻找完全通用的东西,则无法做到,因为属性查找是动态的。正如文档所说:

尝试返回该对象的有效属性列表。

那里的关键词是“尝试”。在下面:

注意 因为提供 dir() 主要是为了方便在交互式提示下使用,所以它尝试提供一组有趣的名称比它尝试提供一组严格或一致定义的名称要多,并且它的详细行为可能会随着版本的不同而改变. 例如,当参数是类时,元类属性不在结果列表中。

实际上,它所能做的就是查看__dict__对象的类型、类型以及该类型的任何基类。(然后它减去了一些东西——例如,类型的属性被跳过以避免暴露元类属性,你通常不关心)。如果您想了解确切的详细信息,请阅读上面链接的文档。

同时,如果对象具有上述的__getattr__/ __setattr__/ __delattr__、 or__getattribute__或 C-API 等价物,则它可能具有任何字典中都不存在的各种属性,甚至可能具有无限的属性集。例如:

class C(object):
    def __getattr__(self, name):
        return name
c = C()
print(c.a)

这将打印出来a。但怎么dir可能知道c.a存在呢?即使它可以解释我的代码,它也必须打印出所有可能字符串的列表,这显然是您不想要的。

还有一些特殊的属性名称在解释器的掩护下以奇特的方式处理。

此外,任何对象都可以定义一个__dir__方法来返回它想要的任何东西。

如果您正在寻找特定的东西,您可能可以这样做。例如,如果您只是想在不减去元类属性的情况下获取属性,那只是dir(x) + dir(type(x)),或者,也许更好,dir(x) + [a for a in dir(type(x)) if a not in dir(x)](删除重复项)。

但是如果你想知道一个对象的所有属性,那么你做不到。

于 2013-02-02T00:57:46.303 回答