У меня есть скрипт Python, который выполняет большую работу по анализу файла Word .docx (и он работал на всех предыдущих файлах).Внезапно он перестает работать на полпути без каких-либо исключений.Весь код обернут внутри предложения try-исключением, в основном так:
try:
report.read_and_postprocess() #: My parsing process (with ALOT of code inside)
print("Finished...")
except NoObjectForElementError as error:
print("Known error")
raise error
except:
print("Other error")
raise
finally:
print("Write this!")
Чтобы найти ошибку, я попытался использовать операторы print()
, чтобы изолировать, где код останавливается.Тем не менее, когда я подхожу близко, точка остановки перемещается в другое место.
Это заставляет меня думать, что есть утечка памяти или, возможно, какое-то другое ограничение в моей среде Python, которое включается - ноЯ не очень квалифицирован в отладке этого.Я посмотрел на использование памяти и процессора моего скрипта.В конце сценария он занимает всего около 87 МБ памяти, в результате чего общая память компьютера перемещается только с 67% до 68%.(Я смотрю только на диспетчер задач Windows 10 для этого, поэтому я не могу гарантировать, что память на мгновение не скачет до остановки скрипта)
Я перезапускал скрипт сотни раз и никогда не получалсообщение об ошибке, кроме двух раз с этой ошибкой:
Python Fatal Error: GC Object already Tracked
Понятия не имею, как продолжить отладку, есть у кого-нибудь какие-нибудь советы?Скорее всего, это вызвано памятью, или как я могу узнать?Есть ли какие-то другие ограничения Python, которые могут вызвать это?(Я читал, например, о 20-предельном числе вложенных циклов for - но это не должно быть для меня)
Обновление: Останавливается во время строки report.read_and_postprocess()
.
Информация об окружении: Windows 10, Anaconda 3, Python 3.7.Скрипт запускается в приглашении anaconda с активированной средой.
Обновление: Я нашел этот совет: https://stackoverflow.com/a/3443779/6700475 Может показаться, что мой код тратит много времени на оценкурегулярные выражения.В основном, такие линии были обычными при наблюдении за трассировкой:
sre_compile.py(596): return isinstance(obj, (str, bytes))
sre_compile.py(763): pattern = p
sre_compile.py(764): p = sre_parse.parse(p, flags)
--- modulename: sre_parse, funcname: parse
sre_parse.py(922): source = Tokenizer(str)
--- modulename: sre_parse, funcname: __init__
sre_parse.py(225): self.istext = isinstance(string, str)
sre_parse.py(226): self.string = string
sre_parse.py(227): if not self.istext:
sre_parse.py(229): self.decoded_string = string
sre_parse.py(230): self.index = 0
sre_parse.py(231): self.next = None
sre_parse.py(232): self.__next()
--- modulename: sre_parse, funcname: __next
sre_parse.py(234): index = self.index
sre_parse.py(235): try:
sre_parse.py(236): char = self.decoded_string[index]
sre_parse.py(240): if char == "\\":
sre_parse.py(247): self.index = index + 1
sre_parse.py(248): self.next = char
sre_parse.py(924): if pattern is None:
sre_parse.py(925): pattern = Pattern()
--- modulename: sre_parse, funcname: __init__
sre_parse.py(77): self.flags = 0
sre_parse.py(78): self.groupdict = {}
Я запустил трассировку и (по крайней мере, на этот раз) она остановилась во время повторного матча, в частности, на третьей итерацииloop:
def is_numeric(text):
""" Return whether a trimmed string is numeric
Numeric formats:
1
1.2 (US style)
1,2 (EU style)
1,200,340 (US style)
1 200 340 (other style)
1.200.340 (eu style?)
1,200,340.67
1 200 340,67
1 200 340.67
1.200.340,67
-23
-23.98
-2 454 981.21
+ 24
- 24
+ 24.9183
12321
543525,-
123123,
12389.
12 489.
12 432,
"""
if len(text) == 0:
return False
#: Try float
try:
float(text)
except ValueError:
pass
except:
raise
else:
return True
#: look for all characters that should not be in a number
if not re.match(r"^[-+0-9., ]*$", text):
return False
#: Verify numeric format
#: 1.200.200,78
#: 1,200,200.78
#: 1 200 200,78
#: 1 200 200.78
#: 1200200,78
#: 1200200.78
#: - 1200200.78
#: + 1.200.200,78
#: 1200200,-
#: -1 200 200,-
#: etc.
variants = ((r",", r"\."),
(r"\.", r","),
(r" ", r","),
(r" ", r"\."))
for (tho, dec) in variants:
dec_exp_opt = r"(%s[0-9]*)" % dec
if dec == ",":
dec_exp_opt = r"((%s)|(,-))" % dec_exp_opt
threesep = r"[1-9][0-9]{0,2}(%s[0-9]{3})*(%s)?" % (tho, dec_exp_opt)
nullsep = r"(([0-9]*(%s[0-9]+)?)|([0-9]+(%s)?))" % (dec, dec_exp_opt)
expr = r"^([-+][ \t]*)?((%s)|(%s))$" % (threesep, nullsep)
test = re.match(expr, text) #: IT HAS STOPPED HERE IN ITERATION 3!!
if test:
return True
return False
Может быть (или не может) быть случайным, что выражение, которое он пытается решить в это время: ^([-+][ \t]*)?(([1-9][0-9]{0,2}( [0-9]{3})*((((,[0-9]*))|(,-)))?)|((([0-9]*(,[0-9]+)?)|([0-9]+((((,[0-9]*))|(,-)))?))))$
для значения 2017-05-29
(которое предпочтительно должно возвращать false).
Имеет ли смысл, что (плохие?) Регулярные выражения могут привести к тому, что скрипт просто остановится, не вызывая исключение?Есть ли в модуле re
некоторое кэширование, которое может вызвать это?