Closed mpainenz closed 8 years ago
There could definitely be a simpler way -- at the moment, the majority of my code uses the get()
method to do things with this. Here are two example ways to iterate.
#!/usr/bin/env python
from tmp import test
x = test()
x.a_list.add(1)
x.test.number = 1
def recursive_get(obj):
if hasattr(obj, "_pyangbind_elements"):
for i in obj._pyangbind_elements:
print i
recursive_get(getattr(obj, i))
else:
pyb_attr = getattr(obj, "_pybind_generated_by", None)
if pyb_attr == "YANGListType":
for i in obj:
print i
recursive_get(obj[i])
else:
print obj
recursive_get(x)
print "\n------\n"
def base_get(obj):
d = {}
for element_name in obj._pyangbind_elements:
element = getattr(obj, element_name, None)
if hasattr(element, "yang_name"):
# retrieve the YANG name method
yang_name = getattr(element, "yang_name", None)
element_id = yang_name()
else:
element_id = element_name
if hasattr(element, "get"):
# this is a YANG container that has its own
# get method
d[element_id] = element.get()
else:
d[element_id] = element
return d
print base_get(x)
It'd certainly be possible to implement an iterator such that one could do 'for x in y' type constructs, I just haven't done this yet. The main use of iterating through objects is serialisation/deserialisation - some other examples of iterating are in lib/serialise: https://github.com/robshakir/pyangbind/blob/master/pyangbind/lib/serialise.py
r.
Note, you don't need to rewrite the latter as this is the standard .get() method which will recurse anyway.
Yes, lib/serialise is where I based my code in my example.
Iter would be awesome... being able to do 'for leaf in pybinding.leafs', 'for leaflist in pybinding.leaflists', 'for container in pybinding.containers', 'for typedlist in pybinding.typedlists'...
Also, iterating through a typed list is another thing, at the moment I use something like:
list[pybind_list.keys()[0]]
I have yet to start iterating through, as I'm not quite there yet, but I found this cumbersome.
I will have a look at .get(), as that may solve a lot of these issues
I had thought that .get returned a python based class structure, so all objects would be returned using python built-in classes, is that not the case?
How do you mean a typed list? A pyangbind.lib.yangtypes.TypedList
item is just a list, so it can be iterated through using for x in leaf_list
. A YANGListType
list can be iterated through using for item in yang_list
.
get()
does not flatten leaf types, it just restructures the classes into nested dicts, one still needs to handle the fact that these are not really native types in serialisation or deserialisation.
r.
Sorry if I'm getting my Yang terminology mixed up with lists.
What I'm referring to is not a leaf list, rather a list of Yang defined types. When I saw the keyword TypedList, that's what I thought it was in reference to.
In the case of a list of Yang defined types with key values, what would be great would be to simplify the following:
for i in xrange(len(endpoint_list.keys())):
endpoint = endpoint_list[endpoint_list.keys()[i]]
To instead be:
for endpoint in endpoint_list:
I assume that somehow the iter needs to be defined for each keyed list class.
Sorry, I'm confused. I think the enhancement you're asking for is already implemented - this is specifically for a YANG list
which has a key specified (the same should work where there is no key specified too).
print "iterating through keys, as per a dict"
for q in x.a_list:
print "key: \t %s" % q
print "value: \t %s" % x.a_list[q].get()
print "\n\n"
print "iterating through key,value tuples as per a dict"
for k,v in x.a_list.iteritems():
print "%s->%s" % (k, v.get())
Please re-open this issue if you have problems with how this works.
r.
Thanks Rob, sorry for the confusion. This works well.
Hi Rob,
Is there a good way to dynamically iterate through the class structure of a binding object?
At the moment I am doing the following:
I can't help but feel like there could be a simpler way to iterate through the hierarchy. What do you think?
Thanks, Mark