Is there another way to iterate through only the attributes of a custom class that are not in-built (e.g. __dict__, __module__, etc.)? For example, in this code:
class Terrain:
    WATER = -1
    GRASS = 0
    HILL = 1
    MOUNTAIN = 2
I can iterate through all of these attributes like this:
for key, value in Terrain.__dict__.items():
    print("{: <11}".format(key), " --> ", value)
which outputs:
MOUNTAIN     -->  2
__module__   -->  __main__
WATER        -->  -1
HILL         -->  1
__dict__     -->  <attribute '__dict__' of 'Terrain' objects>
GRASS        -->  0
__weakref__  -->  <attribute '__weakref__' of 'Terrain' objects>
__doc__      -->  None
If I just want the integer arguments (a rudimentary version of an enumerated type), I can use this:
for key, value in Terrain.__dict__.items():
    if type(value) is int: # type(value) == int
        print("{: <11}".format(key), " --> ", value)
this gives the expected result:
MOUNTAIN    -->  2
WATER       -->  -1
HILL        -->  1
GRASS       -->  0
Is it possible to iterate through only the non-in-built attributes of a custom class independent of type, e.g. if the attributes are not all integral. Presumably I could expand the conditional to include more types, but I want to know if there are other ways I'm missing.
If you want to iterate over the class, you have to define a metaclass which supports iteration. . This way the values will only kept as long as there is a "strong" reference keeping it, such as a in this case. After del a , there are only weak references pointing to the object, so they can be gc'ed.
You can create an iterator object by implementing the iter built-in function to an iterable. An iterator can be used to manually loop over the items in the iterable. The repeated passing of the iterator to the built-in next function returns successive items in the stream.
Method 1: To get the list of all the attributes, methods along with some inherited magic methods of a class, we use a built-in called dir() . Method 2: Another way of finding a list of attributes is by using the module inspect .
I would use:
for key, value in Terrain.__dict__.items():
    if not key.startswith("__"):
        print(...)
Or I would create an actual enumerated type that did what I wanted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With