Я пишу скрипт, который связан с сканированием каталогов, и заметил серьезную утечку памяти при вызове os.path.isdir, поэтому я пробовал следующий фрагмент:
def func():
if not os.path.isdir('D:\Downloads'):
return False
while True:
func()
В течение нескольких секунд процесс Python достиг 100 МБ ОЗУ.
Я пытаюсь понять, что происходит. Похоже, что огромная утечка памяти действует только тогда, когда путь действительно является допустимым пути к каталогу (это означает, что "return False" не выполняется). Кроме того, интересно посмотреть, что происходит в связанных вызовах, например os.path.isfile.
Мысли?
Edit: Я думаю, что на что-то. Хотя isfile и isdir реализованы в модуле genericpath, в системе Windows - isdir импортируется из встроенного nt. Поэтому мне пришлось загрузить источник 2.7.3 (который я должен был сделать давно...).
После небольшого поиска я обнаружил функцию posix__isdir в \Modules\posixmodule.c, которая, как я полагаю, является функцией isdir, импортированной из nt.
Эта часть функции (и комментариев) привлекла мое внимание:
if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
attributes = GetFileAttributesW(wpath);
if (attributes == INVALID_FILE_ATTRIBUTES)
Py_RETURN_FALSE;
goto check;
}
/* Drop the argument parsing error as narrow strings
are also valid. */
PyErr_Clear();
Кажется, что все это сводится к ошибкам обработки Unicode/ASCII.
Я только что попробовал свой фрагмент выше с аргументом пути в unicode (т.е. u'D:\Downloads)) - никакой утечки памяти вообще нет. ха-ха.