If you want to iterate over the class, you have to define a metaclass which supports iteration.

x.py:

class it(type):
    def __iter__(self):
        # Wanna iterate over a class? Then ask that class for iterator.
        return self.classiter()

class Foo:
    __metaclass__ = it # We need that meta class...
    by_id = {} # Store the stuff here...

    def __init__(self, id): # new isntance of class
        self.id = id # do we need that?
        self.by_id[id] = self # register istance

    @classmethod
    def classiter(cls): # iterate over class by giving all instances which have been instantiated
        return iter(cls.by_id.values())

if __name__ == '__main__':
    a = Foo(123)
    print list(Foo)
    del a
    print list(Foo)

As you can see in the end, deleting an instance will not have any effect on the object itself, because it stays in the by_id dict. You can cope with that using weakrefs when you

import weakref

and then do

by_id = weakref.WeakValueDictionary()

. 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.

Due to the warning concerning WeakValueDictionary()s, I suggest to use the following:

[...]
    self.by_id[id] = weakref.ref(self)
[...]
@classmethod
def classiter(cls):
    # return all class instances which are still alive according to their weakref pointing to them
    return (i for i in (i() for i in cls.by_id.values()) if i is not None)

Looks a bit complicated, but makes sure that you get the objects and not a weakref object.

Answer from glglgl on Stack Overflow
Top answer
1 of 5
35

If you want to iterate over the class, you have to define a metaclass which supports iteration.

x.py:

class it(type):
    def __iter__(self):
        # Wanna iterate over a class? Then ask that class for iterator.
        return self.classiter()

class Foo:
    __metaclass__ = it # We need that meta class...
    by_id = {} # Store the stuff here...

    def __init__(self, id): # new isntance of class
        self.id = id # do we need that?
        self.by_id[id] = self # register istance

    @classmethod
    def classiter(cls): # iterate over class by giving all instances which have been instantiated
        return iter(cls.by_id.values())

if __name__ == '__main__':
    a = Foo(123)
    print list(Foo)
    del a
    print list(Foo)

As you can see in the end, deleting an instance will not have any effect on the object itself, because it stays in the by_id dict. You can cope with that using weakrefs when you

import weakref

and then do

by_id = weakref.WeakValueDictionary()

. 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.

Due to the warning concerning WeakValueDictionary()s, I suggest to use the following:

[...]
    self.by_id[id] = weakref.ref(self)
[...]
@classmethod
def classiter(cls):
    # return all class instances which are still alive according to their weakref pointing to them
    return (i for i in (i() for i in cls.by_id.values()) if i is not None)

Looks a bit complicated, but makes sure that you get the objects and not a weakref object.

2 of 5
13

Magic methods are always looked up on the class, so adding __iter__ to the class won't make it iterable. However the class is an instance of its metaclass, so the metaclass is the correct place to define the __iter__ method.

class FooMeta(type):
    def __iter__(self):
        return self.by_id.iteritems()

class Foo:
    __metaclass__ = FooMeta
    ...
Top answer
1 of 3
1

Hi @Ronald Rex , Welcome to Microsoft Q&A,

Are there any preconditions?

To iterate over all properties of a POCO class, you can use reflection. In C#, you can use the "Type" class to get information about the properties of an object type.

First use GetType() to get the type of the OrderPoco object. Then, use "GetProperties()" to retrieve an array of "PropertyInfo" objects that represent the class properties. Finally, iterate through the property information and use GetValue() to access the property's values and print them to the console.

Public properties available only for POCO classes. If you have private or protected properties, you will need to modify your code accordingly. In addition, using reflection may reduce performance and needs to be used with caution.

using System;
using System.Reflection;

class Program
{
    static void Main()
    {
        var o = new OrderPoco()
        {
            OrderID = 1,
            CustomerID = "ABCDE",
            Shipper = 3
        };

        // Get the type of the object
        Type type = o.GetType();

        // Get all public properties of the object's type
        PropertyInfo[] properties = type.GetProperties();

        foreach (PropertyInfo property in properties)
        {
            // Get the name and value of each property
            string propertyName = property.Name;
            object propertyValue = property.GetValue(o);

            Console.WriteLine($"{propertyName}: {propertyValue}");
        }
    }
}

class OrderPoco
{
    public int OrderID { get; set; }
    public string CustomerID { get; set; }
    public int Shipper { get; set; }
}

Best Regards,

Jiale


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". 

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

2 of 3
0

What is the purpose of doing this?

You can iterate as shown below to get property names.

foreach (PropertyInfo p in typeof(OrderPoco).GetProperties())
{
    string propertyName = p.Name;
   
}

And use the following method to get values. But still does not get what you want yet I see if as viable.

Discussions

Is there a way I can iterate over the attributes of a class?
You can call dir(Object) to return a list of all the attributes of an object. Note that this will return ALL the attributes of an object, including the base model it's inheriting from. You could then filter that result as you see fit to access only the attributes you care about. https://docs.python.org/3/library/functions.html#dir More on reddit.com
🌐 r/learnpython
9
1
April 13, 2021
How to iterate through class properties of a class? - Questions & Answers - Unity Discussions
Hi guys, I bumped into a problem and I am stucked! I have the following code. I made it simple but in real I have much more variables and I would have a lot of IF statements. Is it possible to iterate through the class Resources? What I want is to count how many values have a value. More on discussions.unity.com
🌐 discussions.unity.com
0
December 5, 2023
loops - How to iterate through class instance - Stack Overflow
Hi i'm trying to solve an simple problem but i don't know how to iterate through class instances i. e. class element : def __init__(self, a, s, m): self.name = a ; self.symbol... More on stackoverflow.com
🌐 stackoverflow.com
iterate through classes on same element - javascript
If I have a div which has multiple classes assigned to the class attribute, is it possible to iterate through them using the each() function in jQuery? More on stackoverflow.com
🌐 stackoverflow.com
🌐
Reddit
reddit.com › r/learnpython › is there a way i can iterate over the attributes of a class?
r/learnpython on Reddit: Is there a way I can iterate over the attributes of a class?
April 13, 2021 -

I am fairly new to python, and have been working on creating 'Worldbuilding' app, That lets the user perform CRUD operations on a database from a UI.

I am using SQLAlchemy's ORM to model my data structure as following:

class Character(base):
    __tablename__ = "Character"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    home_town = Column(String)
    age = Column(Integer)


    def get_columns(self):
        return ["id", "name", "home_town", "age"]

    def get_values(self):
        return [self.id, self.name, self.home_town, self.age]

example = Character(name="Bilbo", home_town="The Shire", age=111)

I want to get a list of my 'columns' (attributes) and the values for each 'row' (Instance).

I have written two 'get_' methods for this, but they feel very arbitrary and undynamic (for instance, adding new attributes would require me to edit the methods as well).

The closest thing I have found so far is the class's __dict__ attribute, but I ideally want my output as a list if possible.

I would greatly appreciate any help :)

Top answer
1 of 2
2
You can call dir(Object) to return a list of all the attributes of an object. Note that this will return ALL the attributes of an object, including the base model it's inheriting from. You could then filter that result as you see fit to access only the attributes you care about. https://docs.python.org/3/library/functions.html#dir
2 of 2
2
Yes: dir. For example, on the str class: >>> # all attributes >>> dir(str) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] >>> >>> >>> # only attributes that return bool >>> [attr for attr in dir(str) if attr.starswith('is')] ['isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper'] >>> >>> >>> # only methods >>> [attr for attr in dir(str) if callable(getattr(str, attr))] ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] There's even an easy way to get a dict of all attributes with attribute names as keys and repr as values: >>> str.__dict__ mappingproxy({'__repr__': , '__hash__': , '__str__': , '__getattribute__': , '__lt__': , '__le__': , '__eq__': , '__ne__': , '__gt__': , '__ge__': , '__iter__': , '__mod__': , '__rmod__': , '__len__': , '__getitem__': , '__add__': , '__mul__': , '__rmul__': , '__contains__': , '__new__': , 'encode': , 'replace': , 'split': , 'rsplit': , 'join': , 'capitalize': , 'casefold': , 'title': , 'center': , 'count': , 'expandtabs': , 'find': , 'partition': , 'index': , 'ljust': , 'lower': , 'lstrip': , 'rfind': , 'rindex': , 'rjust': , 'rstrip': , 'rpartition': , 'splitlines': , 'strip': , 'swapcase': , 'translate': , 'upper': , 'startswith': , 'endswith': , 'isascii': , 'islower': , 'isupper': , 'istitle': , 'isspace': , 'isdecimal': , 'isdigit': , 'isnumeric': , 'isalpha': , 'isalnum': , 'isidentifier': , 'isprintable': , 'zfill': , 'format': , 'format_map': , '__format__': , 'maketrans': , '__sizeof__': , '__getnewargs__': , '__doc__': "str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'."}) Take your pick :)
🌐
Unity
discussions.unity.com › questions & answers
How to iterate through class properties of a class? - Questions & Answers - Unity Discussions
December 5, 2023 - Hi guys, I bumped into a problem and I am stucked! I have the following code. I made it simple but in real I have much more variables and I would have a lot of IF statements. Is it possible to iterate through the class Resources? What I want is to count how many values have a value.
🌐
W3Schools
w3schools.com › python › python_iterators.asp
Python Iterators
We can also use a for loop to iterate through an iterable object: ... The for loop actually creates an iterator object and executes the next() method for each loop. To create an object/class as an iterator you have to implement the methods ...
🌐
Stack Overflow
stackoverflow.com › questions › 50468078 › how-to-iterate-through-class-instance
loops - How to iterate through class instance - Stack Overflow
class a: def __init__(self, a: str, b: str): this.a = a this.b = b inst = a("str1", "str2") setattr(inst, "a", "new_string_1")
Find elsewhere
🌐
CodingTechRoom
codingtechroom.com › question › iterate-through-objects-class-java
How to Iterate Through All Objects of a Specific Class in Java? - CodingTechRoom
This approach involves using static collections to store references of created objects, allowing you to iterate through them later. ... public class YourClass { private static List<YourClass> instances = new ArrayList<>(); public YourClass() { instances.add(this); } public static List<YourClass> ...
🌐
Python Forum
python-forum.io › thread-12462.html
iterate over class properties?
August 26, 2018 - is there a way to iterate over python property descriptors rather than __dict__ attributes? import datetime from datetime import date from datetime import datetime as dt class videofile: def __init__(self): self._date = date.today() ...
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › csharp › programming-guide › concepts › iterators
Iterate through collections - C# | Microsoft Learn
The foreach statement that refers to the class instance (theZoo) implicitly calls the GetEnumerator method. The foreach statements that refer to the Birds and Mammals properties use the AnimalsForType named iterator method.
🌐
Programiz
programiz.com › python-programming › iterator
Python Iterators (With Examples)
Let's see an example that will give us the next power of 2 in each iteration. Power exponent starts from zero up to a user set number, class PowTwo: """Class to implement an iterator of powers of two""" def __init__(self, max=0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: result = 2 ** self.n self.n += 1 return result else: raise StopIteration # create an object numbers = PowTwo(3) # create an iterable from the object i = iter(numbers) # Using next to get to the next iterator element print(next(i)) # prints 1 print(next(i)) # prints 2 print(next(i)) # prints 4 print(next(i)) # prints 8 print(next(i)) # raises StopIteration exception
🌐
Reddit
reddit.com › r/learnpython › iterate through a list or dict of custom class objects
r/learnpython on Reddit: Iterate through a list or dict of custom class objects
June 1, 2023 -

Hi,

So i have a dictionary which contains instances of several classes, which kinda looks like

d = {"key1" : object,... }

where object can be of type root.class1.class2.abc.class3, root.class1.class2.def.class4 and so on. And these objects have additional variables like

Obj._name = "some_name";

Obj._args = {key1: value, key2: class_object}

What I have to do is look into all these objects and find some variable names and get their values. So input request could look like

class_type = "abc.class3"

param_name = "_args.key2"

Right now I'm doing like

if class_type in str(type(obj)): blah blah

to locate class_type of the object and then use obj.get('some_name') if it's a dict, obj.getattr('some_name') if the type is dict with an occasional if 'some_name in vars(obj)` to check if name exists in class object.

The code works but it's a mess as there are too many isinatance calls and kinda long because everywhere I'm handing inputs based on their type. It looks like lot of straws taped together and I feel like the code is gonna break if some unexpected input is given.

Is there some library available that can recursively look inside an objects/sub-objects/sub-sub-objects (list/dict/class) and tell me if some name exists and it's value.

Right now I don't even know what query to type in google to search for such a library. If you can tell me some keywords to make search queries, even that would help. My poorly formed search queries are giving me stuff about iterating through lists or dicts

Top answer
1 of 2
1
This is called "introspection". As an example, a very rough implementation looks like this: def find_in_object(obj, class_type, param_name): # If the object is a dictionary, recursively call this function on each item. if isinstance(obj, dict): for key, value in obj.items(): result = find_in_object(value, class_type, param_name) if result is not None: return result # If the object is a list, recursively call this function on each item. elif isinstance(obj, list): for item in obj: result = find_in_object(item, class_type, param_name) if result is not None: return result # If the object is an instance of the class type, check if it has the parameter. elif class_type in str(type(obj)): # If param_name is in the format '_args.key', we need to handle it differently. if param_name.startswith('_args.'): # Remove '_args.' from the param_name. param_name = param_name[6:] # Get the _args attribute from the object. if hasattr(obj, '_args') and isinstance(getattr(obj, '_args'), dict): args_dict = getattr(obj, '_args') if param_name in args_dict: return args_dict[param_name] elif hasattr(obj, param_name): return getattr(obj, param_name) return None You can call this function with your dictionary, class type, and parameter name, and it should return the parameter value if it exists. d = {"key1": obj1, "key2": obj2} class_type = "abc.class3" param_name = "_args.key2" value = find_in_object(d, class_type, param_name)
2 of 2
1
It sounds like a tree, There are 2-3 ways I would approach this. Database, SQlite would do for local at least at first. Create tables for all the discreet objects in your program and use an ORM like pony-orm or sqlalchemy to describe relationships between them. Databases are good at this stuff Network/graph DB/data structure. It sound slike you may have a tree or graph like data structure. Use a tree data structure instead of dicts (many implem,entations are subclasses of dict) or fully commit and use networkX or a full graph database like neo4j Keep it all in python and RAM and use a 3rd party package like anytree or build your own to manage your data like a tree with the ability to query generically (my_thing.children.class_filter(Class3).filter('score', lambda x: score<10).first()) etc.
Top answer
1 of 2
1

You put all your Moons and Planets in a list.

for item in moons_planets_list:
    if item.name == user_input:
        #Do sth
2 of 2
1

Ordinarily, taking note of all instances of a class is not done automatically by Python or other languages.

However, you can do that by adding code in the __init__ method to register each instance as it is created in a "registry"of your choice. This "registry" is any data structure which will track your instances - a simple dictionary can be enough for most cases. You can then just keep this dictionary at the module level, or as a class attribute: an attribute that is present on the class and shared across all instances.

If one is not doing some "production level code" which would have to handle all sorts of random events and misuses (for example, if one creates a Planet with a name that is already registered), the code can be quite simple.

Since the code would be common across Planets and Moons, it is a case for using class inheritance, and share the common functionality, without the functionality getting in the way of what you want to handle in Planets

class Registerable:
    registry = {}
    def __init__(self, name):
        cls = self.__class__ # optional for readability
        cls.registry[name] = self
        super().__init__()
    

class Planets(Registerable):
    registry = {}
    def __init__(self, name, radius, sgp, soi, atmo_height, moons=()):
        super().__init__(name)
        self.name = name
        self.radius = radius
        self.sgp = sgp
        self.soi = soi
        self.atmo_height = atmo_height
        self.moons = moons

...
class Moons(Planeys):
    registry = {}  # each class have to declare its own registry, otherwise they are all shared with the base class

And then you can iterate on your instances using Planets.registry and Moons.registry as normal Python dictionaries.

🌐
PHP
php.net › manual › en › language.oop5.iterations.php
PHP: Object Iteration - Manual
PHP provides a way for objects to be defined so it is possible to iterate through a list of items, with, for example a foreach statement. By default, all visible properties will be used for the iteration.