Если вы имеете в виду, может ли функция действовать по-разному в зависимости от типов возвращаемых данных, ожидаемых вызывающей стороной, ответ отрицательный (за исключением серьезной неприятной проверки байт-кода). В этом случае вы должны предоставить два разных итератора для вашего объекта и написать что-то вроде:
for item in something: # Default iterator: returns non-tuple objects
do_something(item)
for (item,key) in something.iter_pairs(): # iter_pairs returns different iterator
do_something_else(item, key)
например. посмотрите объект словаря, который использует этот шаблон. for key in mydict
перебирает ключи словаря. for k,v in mydict.iteritems()
перебирает пары (ключ, значение).
[Редактировать] На всякий случай, если кто-то захочет увидеть, что я имею в виду под «серьезно неприятной проверкой байт-кода», вот быстрая реализация:
import inspect, opcode
def num_expected_results():
"""Return the number of items the caller is expecting in a tuple.
Returns None if a single value is expected, rather than a tuple.
"""
f = inspect.currentframe(2)
code = map(ord, f.f_code.co_code)
pos = f.f_lasti
if code[pos] == opcode.opmap['GET_ITER']: pos += 1 # Skip this and the FOR_ITER
if code[pos] > opcode.EXTENDED_ARG: pos +=5
elif code[pos] > opcode.HAVE_ARGUMENT: pos +=3
else: pos += 1
if code[pos] == opcode.opmap['UNPACK_SEQUENCE']:
return code[pos+1] + (code[pos+2] << 8)
return None
Можно использовать что-то вроде:
class MagicDict(dict):
def __iter__(self):
if num_expected_results() == 2:
for k,v in self.iteritems():
yield k,v
else:
for k in self.iterkeys():
yield k
d=MagicDict(foo=1, bar=2)
print "Keys:"
for key in d:
print " ", key
print "Values"
for k,v in d:
print " ",k,v
Отказ от ответственности: Это невероятно хакерская, безумно плохая практика, и заставит заставить других программистов выследить вас и убить вас, если они когда-нибудь увидят это в реальном коде. Работает только на cpython (если что). Никогда не используйте это в производственном коде (или в этом отношении, вероятно, любой код).