On 10.9.2015 16:30, Mike Bayer wrote: > On 9/10/15 10:26 AM, Mike Bayer wrote: >> >> >> On 9/10/15 10:13 AM, Ladislav Lenart wrote: >>> Hello. >>> >>> Just a really, really tiny and pedantic correction... The stack >>> variable in the >>> code is in fact a queue. This could potentially surprise some users / >>> readers. >>> >>> To fix, please do one of the following: >>> * Rename stack local var to queue. >>> * Use stack.pop() to pop the last element from the stack. >> >> there really should be some other name, because all the time, I have >> routines like this where even dynamically within the routine, the >> pop(0) is a pop() or vice-versa, because we'd like the iteration to >> work one way or another. Changing pop(0) to pop() here means we are >> doing depth-first instead of breadth-first. So. Some word that means >> "collection of things to operate upon"? I've seen "work" used. >> "buffer" ? eh. >> > > renamed to "deque".
Well, for me the name 'stack' automatically means depth-first whereas the name 'queue' means breadth-first. And when the name and the code do not match, I am not sure what is the original intent. However, deque (or maybe dequeue?) is a fine name for me. BTW I've noticed that you use the term 'seen' for the set of already visited objects. Perhaps you will like the name 'visit' (or 'to_visit' or 'not_visited')? At least that's what I use when I implement a visitor / iterator pattern. HTH, Ladislav Lenart >>> HTH, >>> >>> Ladislav Lenart >>> >>> >>> On 10.9.2015 15:48, Mike Bayer wrote: >>>> >>>> On 9/10/15 9:35 AM, Mike Bayer wrote: >>>>> >>>>> On 9/10/15 8:48 AM, Pavel S wrote: >>>>>> Let's say, I have declarative classes A, B, C, D. >>>>>> >>>>>> A is the parent >>>>>> B has FK&relationship to A >>>>>> C has FK&relationship to B, >>>>>> D has FK&relationship to C etc... >>>>>> >>>>>> I'd like to implement _generic method_ walk(obj) which will >>>>>> recursively yield >>>>>> dependent/related objects of obj (which is instance of A). >>>>>> >>>>>> I know that there is introspection interface inspect(), however >>>>>> I'm don't >>>>>> really understand how to use it properly in my use case. >>>>>> >>>>>> Shall I do inspect(obj) or rather inspect(obj.__class__) and then >>>>>> somehow >>>>>> apply inspection to obj? >>>>>> >>>>>> Are there an examples and best practices? >>>>> right now you can kind of get this effect using cascade_iterator: >>>>> http://docs.sqlalchemy.org/en/rel_1_0/orm/mapping_api.html?highlight=cascade_iterator#sqlalchemy.orm.mapper.Mapper.cascade_iterator >>>>> >>>>> >>>>> >>>>> the limitation is that right now its based on relationship cascade >>>>> settings, >>>>> as that's what it was intended for, so you'd probably want to use >>>>> "save-update": >>>>> >>>>> insp = inspect(my_object) >>>>> for obj in insp.mapper.cascade_iterator("save-update", insp): >>>>> # ... >>>>> >>>>> to implement your own system, the graph of objects is strictly >>>>> based on >>>>> relationship. so walk() is pretty simple: >>>>> >>>>> def walk(obj): >>>>> yield obj >>>>> insp = inspect(obj) >>>>> for relationship in insp.mapper.relationships: >>>>> related = getattr(obj, relationship.key) >>>>> if relationship.uselist: >>>>> for collection_member in related: >>>>> for walk_related in walk(collection_member): >>>>> yield walk_related >>>>> elif related is not None: >>>>> for walk_related in walk(related): >>>>> yield walk_related >>>> here's one im putting in the FAQ for now, which solves recursion >>>> depth as well >>>> as cycles: >>>> >>>> def walk(obj): >>>> stack = [obj] >>>> >>>> seen = set() >>>> >>>> while stack: >>>> obj = stack.pop(0) >>>> if obj in seen: >>>> continue >>>> else: >>>> seen.add(obj) >>>> yield obj >>>> insp = inspect(obj) >>>> for relationship in insp.mapper.relationships: >>>> related = getattr(obj, relationship.key) >>>> if relationship.uselist: >>>> stack.extend(related) >>>> elif related is not None: >>>> stack.append(related) >>>> >>>> >>>> >>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups >>>>>> "sqlalchemy" group. >>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>> send an >>>>>> email to [email protected] >>>>>> <mailto:[email protected]>. >>>>>> To post to this group, send email to [email protected] >>>>>> <mailto:[email protected]>. >>>>>> Visit this group at http://groups.google.com/group/sqlalchemy. >>>>>> For more options, visit https://groups.google.com/d/optout. >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups >>>>> "sqlalchemy" group. >>>>> To unsubscribe from this group and stop receiving emails from it, >>>>> send an >>>>> email to [email protected] >>>>> <mailto:[email protected]>. >>>>> To post to this group, send email to [email protected] >>>>> <mailto:[email protected]>. >>>>> Visit this group at http://groups.google.com/group/sqlalchemy. >>>>> For more options, visit https://groups.google.com/d/optout. >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups >>>> "sqlalchemy" group. >>>> To unsubscribe from this group and stop receiving emails from it, >>>> send an email >>>> to [email protected] >>>> <mailto:[email protected]>. >>>> To post to this group, send email to [email protected] >>>> <mailto:[email protected]>. >>>> Visit this group at http://groups.google.com/group/sqlalchemy. >>>> For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.
