Looping Over All Member Variables of a Class in Python

looping over all member variables of a class in python

dir(obj)

gives you all attributes of the object.
You need to filter out the members from methods etc yourself:

class Example(object):
bool143 = True
bool2 = True
blah = False
foo = True
foobar2000 = False

example = Example()
members = [attr for attr in dir(example) if not callable(getattr(example, attr)) and not attr.startswith("__")]
print members

Will give you:

['blah', 'bool143', 'bool2', 'foo', 'foobar2000']

Iterate over object attributes in python

Assuming you have a class such as

>>> class Cls(object):
... foo = 1
... bar = 'hello'
... def func(self):
... return 'call me'
...
>>> obj = Cls()

calling dir on the object gives you back all the attributes of that object, including python special attributes. Although some object attributes are callable, such as methods.

>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo', 'func']

You can always filter out the special methods by using a list comprehension.

>>> [a for a in dir(obj) if not a.startswith('__')]
['bar', 'foo', 'func']

or if you prefer map/filters.

>>> filter(lambda a: not a.startswith('__'), dir(obj))
['bar', 'foo', 'func']

If you want to filter out the methods, you can use the builtin callable as a check.

>>> [a for a in dir(obj) if not a.startswith('__') and not callable(getattr(obj, a))]
['bar', 'foo']

You could also inspect the difference between your class and its instance object using.

>>> set(dir(Cls)) - set(dir(object))
set(['__module__', 'bar', 'func', '__dict__', 'foo', '__weakref__'])

How to iterate over class attributes but not functions and returning the attribute values in python?

Use the getattr function

members = [getattr(self, attr) for attr in dir(self) if not attr.startswith("__")]

getattr(self, 'attr') is equivalent of self.attr

How to loop over class instance variables without calling methods?

All functions can be called. So, you just need to filter those out:

def info(self):
print('\n'.join("%s: %s" % item
for item in vars(self).items()
if not hasattr(item, '__call__')
))

This will output only the non-callable attributes of the class.

python iterate over class variables and only get values of variables

You can do this by overriding __str__:

from enum import Enum

class Cars(Enum):
BMW = "BMW"
Audi = "Audi"

def __str__(self):
return self.value

This isn't really how enum's should be used, though, so I wouldn't recommend it. Just use the colors as the objects they are, and call on .value when you need it. Better yet you can just use .name:

from enum import auto, Enum

class Cars(Enum):
BMW = auto()
Audi = auto()

for brand in Cars:
print(brand.name)

Iterate Over Instances of a Class in Python

your problem is that you are calling the method recursively and hence in the second round you call it with the object itself instead of the list!

in the for-loop this line:

recursiveCheck(equipment)

you are calling the function with one Equipment object and when it runs, it tries to do the for-loop on this object which is not your list!
you probably wanted your code to be like this:

class Equipment:

def __init__(self, equipmentType, sensor, pin):
self.equipmentType = equipmentType
self.sensor = sensor
self.pin = pin

dht11Sensor = Adafruit_DHT.DHT11

minus20 = Equipment("Minus 20 Freezer", dht11Sensor, 4)
minus80 = Equipment("Minus 80 Freezer", dht11Sensor, 4)
incubator24 = Equipment("24 Degree Incubator", dht11Sensor, 4)
incubator18 = Equipment("18 Degree Incubator", dht11Sensor, 4)

equipment = [minus20, minus80, incubator24, incubator18]

def recursiveCheck(equipmentList):

for equipment in equipmentList:
humidity, temperature = Adafruit_DHT.read(equipment.sensor, equipment.pin)

if humidity is not None and temperature is not None:
print(f"Your {equipment.equipmentType} is currently {temperature} degrees C and the humidity is {humidity}%")

else:
recursiveCheck(equipmentList)

time.sleep(5)
recursiveCheck(equipmentList)

recursiveCheck(equipment)

so to recap, the first time that your code runs, it runs ok and doesn't encounter any error (you could fact-check it with a simple print or a counter), the failure happens when your code goes to else statement in the for-loop because you are trying to pass an object instead of a list!

===
update:

so if you want to start the list from a given index when it fails you could do this:

class Equipment:

def __init__(self, equipmentType, sensor, pin):
self.equipmentType = equipmentType
self.sensor = sensor
self.pin = pin

dht11Sensor = Adafruit_DHT.DHT11

minus20 = Equipment("Minus 20 Freezer", dht11Sensor, 4)
minus80 = Equipment("Minus 80 Freezer", dht11Sensor, 4)
incubator24 = Equipment("24 Degree Incubator", dht11Sensor, 4)
incubator18 = Equipment("18 Degree Incubator", dht11Sensor, 4)

equipment = [minus20, minus80, incubator24, incubator18]

def recursiveCheck(equipmentList, index=0):

for i in in range(index, len(equipmentList)):
equipment = equipmentList[i]
humidity, temperature = Adafruit_DHT.read(equipment.sensor, equipment.pin)

if humidity is not None and temperature is not None:
print(f"Your {equipment.equipmentType} is currently {temperature} degrees C and the humidity is {humidity}%")

else:
recursiveCheck(equipmentList, i)
return;

while True:
recursiveCheck(equipment)
time.sleep(5)

so I have made your function non-recursive because if I didn't do that it would have became a mess in runtime, and it might have gotten hard to follow where it is going!!



Related Topics



Leave a reply



Submit