关于python:有没有其他方法来遍历自定义类的属性,不包括内置类的属性?

Are there any other ways to iterate through the attributes of a custom class, excluding the in-built ones?

本问题已经有最佳答案,请猛点这里访问。

是否有另外一种方法只迭代未内置的自定义类的属性(例如__dict____module__等)?例如,在此代码中:

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

我可以像这样迭代所有这些属性:

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

哪些输出:

1
2
3
4
5
6
7
8
MOUNTAIN     -->  2
__module__   -->  __main__
WATER        -->  -1
HILL         -->  1
__dict__     -->  
GRASS        -->  0
__weakref__  -->  
__doc__      -->  None

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

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

这给出了预期的结果:

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

是否可以只迭代与类型无关的自定义类的非内置属性,例如,如果属性不是全部整数的话。我可以将条件扩展为包含更多类型,但我想知道是否还有其他方法缺少。


我会使用:

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

或者我会创建一个实际的枚举类型来实现我想要的。


你可以尝试这样的方法:

1
2
3
4
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}


内置属性应以"uuuuuuu"开头和结尾,因此:

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

有些人喜欢创建自己的__attributes__,所以这段代码不适合他们。嘿,保留这个名称空间是有原因的

你还得检查一下__slots__