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