As I mentioned what you are trying to do is a very bad idea imho...
But if you really want it you can define __getitem__
method and return value if it's in let's say set of values of your interest and raise StopIteration
otherwise.
This will allow to loop over those attributes using for loop and it won't return neither methods nor other attributes of that object.
class Example:
def __init__(self):
self.a = 0
self.b = 1
self.c = 2
self.other_stuff = [1,None,False]
self.stuff = {"a":2,"b":3,"c":87}
def __getitem__(self, index):
key = list(self.__dict__.keys())[index]
if key in {"a", "b", "c"}:
return self.__dict__[key]
else:
raise StopIteration()
def foo(self):pass
e = Example()
for item in e:
print(f"{item=}")
print(e.__dict__)
Side notes and why you should NOT do that:
- it's unclear what's the purpose of this and it's gonna cause a headache sooner than later
- proper data structures should be used such as
dict
s, dataclass
es and so on
- the dictionaries have guaranteed insert order (python 3.7+ see https://stackoverflow.com/a/60775590/15923186), so when the
__dict__
is created you have to define those attributes you want to loop through in the very specific order, otherwise the StopIteration
will be raised too early and you won't get all the values you want. Which is again very bad, cause it's an implementation detail and anyone using your code doesn't have to know that, neither it's obvious from looking at your code.
To see what I mean just change the order and define Example
like this and again see the output of e.__dict__
:
class Example:
def __init__(self):
self.stuff = {"a":2,"b":3,"c":87}
self.a = 0
self.b = 1
self.c = 2
self.other_stuff = [1,None,False]
...
...
print(e.__dict__)
The code won't work anymore with that change