1

I have a class

class MyClass():
    def __init__(self):
        self.a = 7
        self.b = 2
    @property
    def aAndB(self):
        return self.a + self.b

I would like a function that iterates over all properties and returns only class instances having a certain property.

My goal is a function like this:

def findInstances(listOfInstances, instanceVariable, instanceValue):
    #return all instances in listOfInstances where instanceVariable==instanceValue

Using instance.__dict__ only gives me a and b, but not aAndB. I would like to have a dict of all properties/methods with their values to loop over, so I can search for instances where a certain property (or method decorated with @property) has a certain value.

Currently, calling the function like this

findInstances(someListOfInstances, 'aAndB', '23')

makes Python complain that aAndB is not in instance.__dict__.


Maybe all of you are right and the answers are there, but I still don't get it. All the answers in the mentioned questions get lists, not dictionaries. I want all the properties (including methods with the @property decorator) and their values. Is there a way to iterate over the values of the keys in dir(myClass)? The dir command only contains the names of the attributes, not their values.

I need something like

for a in dir(myClass):
    print a, myClass.(a)  # get the value for an attribute stored in a variable

To be even more clear: The following achieves exactly what I want but there is probably a better way that I don't know.

for a in dir(myClass):
    print a, eval("myClass.{}".format(a))
River
  • 8,585
  • 14
  • 54
  • 67
Stefan
  • 353
  • 2
  • 11
  • You are not the first one who asks for this. Search and you will find plenty of answers which might help you. – Elmex80s Mar 03 '17 at 14:25
  • 2
    Possible duplicate of [Iterate over object attributes in python](http://stackoverflow.com/questions/11637293/iterate-over-object-attributes-in-python) – River Mar 03 '17 at 14:26
  • Possible duplicate of [How to enumerate an object's properties in Python?](http://stackoverflow.com/questions/1251692/how-to-enumerate-an-objects-properties-in-python) – farsil Mar 03 '17 at 14:28
  • @River found this links before, but they want to iterate over variables only, not methods as well. – Stefan Mar 03 '17 at 14:33
  • @Stefan You can just filter them out using `callable` as shown in the answer... Read further down the top answer a bit – River Mar 03 '17 at 14:38
  • @River Sorry, my comment was confusing because I mixed things up. The other questions only want to iterate over variables and not methods, but that's not my problem. The problem is that I want to iterate over the variable names and their values. And I don't know how to get attribute values from a dict using a variable instead of a fixed string. – Stefan Mar 06 '17 at 06:40
  • @Stefan the `eval` method seems ok, especially if it works for you. Using `vars` instead of `dir` will do what you want for non-methods. Honestly I'm a little confused what you want a method to return if it takes parameters. If it will never take parameters, why not make it a variable? e.g. `aAndB = self.a + self.b` – River Mar 06 '17 at 16:53
  • @River The goal for the methods is to provide read-only attributes. A user can enter a simulink model path to a certain block and use the methods with @ parameter properties to easily get information that is hidden in the path (like whether it's a raw signal or not). Also, it can generate full paths to blocks contained in this submodel. So in my example self.a and self.b could be changed by the user but self.aAndB can not. Thanks for the answer. I was sure there must be a better way than using eval. – Stefan Mar 08 '17 at 06:26
  • @Stefan I think I've found your answer. (Little embarrassed I didn't think of `getattr` sooner.) I also cleaned up your question a bit. – River Mar 08 '17 at 16:40

1 Answers1

3

There's actually a very simple way to do this, using getattr in place of eval:

myClass = MyClass()
for a in dir(myClass):
    if(a[:2] != "__"): #don't print double underscore methods
        print a, getattr(myClass, a)

Output:

a 7
aAndB 9
b 2

This has the very big advantage of not needing to hard code in the name of your instance into the string, as is required using eval("myClass.{}".format(a))

River
  • 8,585
  • 14
  • 54
  • 67