Elegantly handle different parameter types
I have a function that, in the simplest of cases, operates on an iterable of items.
def foo(items):
for item in items:
# do stuff
Sometimes, I do not want to pass it an iterable of items directly, but rather an object that provides a method to get the iterable:
def foo(obj):
for item in obj.iteritems():
# do same stuff as above
I can merge these two cases like this:
def foo(obj):
try:
items = obj.iteritems()
except ValueError:
items = obj
for item in items:
# do stuff
This works just fine. Now I get a third use case that looks like this:
def foo(objs):
for item in itertools.chain.from_iterable(obj.iteritems() for obj in objs):
# do same stuff again
I can still use the try-except
approach, since the interfaces are incompatible. However, the nested try catch would start to become very ugly. More so when I want to add a fourth use-case. Is there any way to solve this without nesting the try
-blocks?
As it stands, you should probably use at least two methods here,the third just calling the first with the itertools.chain.from_iterable
result. You could also potentially have a use for *args; it depends on your precise case (providing a real example is helpful). You can also use a simple helper function to return the right type of iterator.
Perhaps this might work out:
def _foo_iter(obj):
try:
return obj.iteritems()
except AttributeError:
return obj
def foo(*objs):
for obj in objs:
for item in _foo_iter(obj):
Must agree with Chris: the magic understand-everything input is going to turn around and bite you. If you pass it an iterable of objects-with-iterables of iterables, how do you specify at what level to actually start processing data?
Far better to stick with "either a list or a generator" as input, then pre-process your calls to the function.
To check if an object is iterable:
import collections
isinstance(obj, collections.Iterable)
This should get you rid of some problems.
Also, a way to handle such problems is by using recursivity (don't know if it's applicable though):
def foo(obj):
if isinstance(obj, collections.Iterable):
for el in obj:
foo(el)
# now do stuff
链接地址: http://www.djcxy.com/p/3982.html
下一篇: 优雅地处理不同的参数类型