Насколько я знаю, единственный способ сделать отслеживание стека доступным для Вашего собственного кода через getStackTrace () метод в Ошибочном классе, точно так же, как Вы уже делаете. В ответ на пример в Вашем вопросе, тем не менее, я упомянул бы, что Вы не должны на самом деле бросать Ошибку - можно просто создать его и назвать метод на нем:
var tempError:Error = new Error();
var stackTrace:String = tempError.getStackTrace();
кроме того, как документация говорит, это только работает в отладочной версии Flash player, таким образом, можно обернуть эту функциональность в если-блок, который проверяет значение Capabilities.isDebugger, если Вы хотите.
Вы можете написать оболочку, которая буферизует некоторое количество элементов из генератора и предоставляет функцию lookahead () для просмотра этих буферизованных элементов:
class Lookahead:
def __init__(self, iter):
self.iter = iter
self.buffer = []
def __iter__(self):
return self
def next(self):
if self.buffer:
return self.buffer.pop(0)
else:
return self.iter.next()
def lookahead(self, n):
"""Return an item n entries ahead in the iteration."""
while n >= len(self.buffer):
try:
self.buffer.append(self.iter.next())
except StopIteration:
return None
return self.buffer[n]
Там довольно хорошие ответы, но я предпочитаю использовать itertools.tee
- с учетом итератора он возвращает два ( или больше, если требуется), которые могут быть расширены независимо. Он буферизует в памяти столько, сколько необходимо (т.е. если итераторы не слишком "расходятся" друг с другом). Например:
import itertools
import collections
class IteratorWithLookahead(collections.Iterator):
def __init__(self, it):
self.it, self.nextit = itertools.tee(iter(it))
self._advance()
def _advance(self):
self.lookahead = next(self.nextit, None)
def __next__(self):
self._advance()
return next(self.it)
Вы можете обернуть любой итератор этим классом, а затем использовать атрибут .lookahead
оболочки, чтобы узнать, какой следующий элемент будет возвращен в будущем. Мне нравится оставлять всю реальную логику itertools.tee и просто предоставлять этот тонкий клей! -)
Это некрасиво, но это может делать то, что вы хотите:
def paired_iter(it):
token = it.next()
for lookahead in it:
yield (token, lookahead)
token = lookahead
yield (token, None)
def scan(s):
for c in s:
yield c
for this_token, next_token in paired_iter(scan("ABCDEF")):
print "this:%s next:%s" % (this_token, next_token)
Печать:
this:A next:B
this:B next:C
this:C next:D
this:D next:E
this:E next:F
this:F next:None
Поскольку вы говорите, что токенизируете строку, а не общую итерацию, я предлагаю простейшее решение - просто расширить ваш токенизатор, чтобы вернуть 3-кортеж:
(token_type, token_value, token_index)
, где token_index
- это индекс токена в строке. Затем вы можете смотреть вперед, назад или в любое другое место в строке. Только не уходи до конца. Я думаю, что это самое простое и гибкое решение.
Кроме того, вам не нужно использовать понимание списка для создания списка из генератора. Просто вызовите на нем конструктор list ():
token_list = list(scan(string))
Вот пример, который позволяет отправить один элемент обратно в генератор
def gen():
for i in range(100):
v=yield i # when you call next(), v will be set to None
if v:
yield None # this yields None to send() call
v=yield v # so this yield is for the first next() after send()
g=gen()
x=g.next()
print 0,x
x=g.next()
print 1,x
x=g.next()
print 2,x # oops push it back
x=g.send(x)
x=g.next()
print 3,x # x should be 2 again
x=g.next()
print 4,x
Павел - хороший ответ. Подход на основе классов с произвольным опережением может выглядеть примерно так:
class lookahead(object):
def __init__(self, generator, lookahead_count=1):
self.gen = iter(generator)
self.look_count = lookahead_count
def __iter__(self):
self.lookahead = []
self.stopped = False
try:
for i in range(self.look_count):
self.lookahead.append(self.gen.next())
except StopIteration:
self.stopped = True
return self
def next(self):
if not self.stopped:
try:
self.lookahead.append(self.gen.next())
except StopIteration:
self.stopped = True
if self.lookahead != []:
return self.lookahead.pop(0)
else:
raise StopIteration
x = lookahead("abcdef", 3)
for i in x:
print i, x.lookahead