11

是否有另一种方法可以仅遍历未内置的自定义类的属性(例如__dict____module__等)?例如,在这段代码中:

class Terrain:
    WATER = -1
    GRASS = 0
    HILL = 1
    MOUNTAIN = 2

我可以像这样遍历所有这些属性:

for key, value in Terrain.__dict__.items():
    print("{: <11}".format(key), " --> ", value)

输出:

MOUNTAIN     -->  2
__module__   -->  __main__
WATER        -->  -1
HILL         -->  1
__dict__     -->  <attribute '__dict__' of 'Terrain' objects>
GRASS        -->  0
__weakref__  -->  <attribute '__weakref__' of 'Terrain' objects>
__doc__      -->  None

如果我只想要整数参数(枚举类型的基本版本),我可以使用它:

for key, value in Terrain.__dict__.items():
    if type(value) is int: # type(value) == int
        print("{: <11}".format(key), " --> ", value)

这给出了预期的结果:

MOUNTAIN    -->  2
WATER       -->  -1
HILL        -->  1
GRASS       -->  0

是否可以仅遍历与类型无关的自定义类的非内置属性,例如,如果属性不都是完整的。大概我可以扩展条件以包含更多类型,但我想知道是否还有其他我遗漏的方法。

4

3 回答 3

19

我会使用:

for key, value in Terrain.__dict__.items():
    if not key.startswith("__"):
        print(...)

或者我会创建一个实际的枚举类型来满足我的需求。

于 2012-07-07T03:09:35.043 回答
3

你可以尝试这样的事情:

class GenericClass(object): pass
class_builtins = set(dir(GenericClass))

terrain_attributes = {attr: getattr(Terrain, attr) for attr in dir(Terrain) if attr not in class_builtins}
于 2012-07-07T03:24:16.617 回答
1

内置属性应该以 '__' 开头和结尾,所以:

[(k,v) for k,v in Terrain.__dict__.items() if not (k.startswith('__')
    and k.endswith('__'))]

有些人喜欢创建自己的__attributes__代码,因此这些代码无法正常工作。嘿,这个命名空间被保留是有原因的

您还必须检查__slots__

于 2012-07-07T04:50:02.470 回答