#python
#python
Вопрос:
У меня есть проект Python для графического интерфейса, который будет использоваться с менеджером очередей slurm в нашем вычислительном кластере. Единственное, что я могу сделать, это распечатать содержимое определенных файлов для конкретного задания в текстовом окне.
Однако расширения, которые люди используют для файлов одного и того же типа, иногда меняются. Я мог бы запрограммировать его так, чтобы он работал для меня, но я также хочу иметь возможность просматривать файлы других людей.
Способ, которым я решил это, заключается в следующем
extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
try:
f = open(jobname ext), "r")
content = f.read()
f.close()
<doing some stuff with content>
except IOError:
if ext == extensions[-1]:
print("File not found")
return
Если фактическое используемое расширение покрыто extensions
, то мой код найдет его. Я хотел бы знать, есть ли у более опытных программистов лучший / более элегантный / более эффективный способ сделать это. К счастью, файлы для чтения очень маленькие, поэтому перебор всех возможностей не займет много времени. Но это конкретное решение может не подойти для других случаев.
Комментарии:
1. Вы могли бы рассмотреть возможность удаления и публикации в Code Review. SE , поскольку Stack Overflow больше подходит для кода, который не работает, в отличие от вопросов о лучших практиках и оптимизации рабочего кода.
2. Почему пользователи не могут вводить расширения файлов вместе с именем файла? В качестве альтернативы, вы могли бы использовать
glob
пакет, чтобы найти все файлы с этим именем (независимо от расширения, например somefilename.*) и попытаться прочитать файл, если он был найден.
Ответ №1:
Насколько я понимаю вопрос, вы уже знаете имя файла и путь, и неизвестно только расширение. Используйте glob
пакет, чтобы найти все файлы с таким именем следующим образом:
from glob import glob
matches = glob("/path/to/files/knownfilename.*")
if not matches:
print("File not found!")
return
try:
with open(matches[0], "r") as f:
content = f.read()
# do stuff
except IOError:
print("Error reading file {}".format(matches[0]))
В этом случае вам, возможно, придется иметь дело с возможностью того, что
- существует несколько файлов с таким именем и разными расширениями
- первый файл в
matches
списке — это не тот файл, который вам нужен (возможно, какой-то файл резервной копии с расширением .bak или что-то еще), поэтому вы также можете захотеть внести в черный список некоторые расширения
Ответ №2:
Вы могли бы использовать with
инструкцию, чтобы открыть файл, а затем автоматически закрыть его. Кроме того, вы могли бы опустить параметр mode на open()
(который по умолчанию равен 'r'
) и, вероятно, добавить break
после того, как вы нашли допустимое расширение:
extensions = [".ex1", ".ext2", "ext3"]
for ext in extensions:
try:
with open(jobname ext)) as f:
content = f.read()
# do some stuff with content
break
except IOError:
if ext == extensions[-1]:
print("File not found")
return
Комментарии:
1. Хотя оба пункта верны, основная проблема не решена. Функция по-прежнему будет находить только файлы с предопределенными расширениями.
Ответ №3:
Вы можете использовать os.listdir('.')
, чтобы получить список имен файлов в текущем рабочем каталоге, выполнить итерацию по списку с помощью for
цикла и вырезать имя файла из длины jobname
и использовать in
оператор, чтобы проверить, является ли это одним из имен расширений в extensions
списке / кортеже. break
после обработки файла, когда найден файл с нужным именем. Используйте else
блок для for
цикла, чтобы напечатать File not found
сообщение, если цикл завершается без прерывания:
import os
extensions = '.ext1', '.ext2', '.ext3'
for filename in os.listdir('.'):
if filename.startswith(jobname) and filename[len(jobname):] in extensions:
with open(filename) as f:
content = f.read()
# doing some stuff with content
break
else:
print("File not found")
Комментарии:
1. Обратите внимание, что это перебирает каждый файл в каталоге, а не проверяет, существует ли один из нескольких возможных файлов. Это будет намного медленнее в каталогах с большим количеством файлов.
Ответ №4:
Даже если это сработает, логика сравнения текущего расширения с концом списка кажется странной. В худшем случае, если последнее расширение случайно дублируется ранее в списке, это приведет к труднодиагностируемым ошибкам.
Поскольку (предположительно) вы уже выходите из цикла, как только находите файл, вы могли бы просто указать поведение «missing-file» после цикла (где оно будет достигнуто, только если файл не был найден), и оставить блок catch пустым:
extensions = [".ex1", ".ext2", ".ext3"]
for ext in extensions:
try:
with open(jobname ext), "r") as f:
content = f.read()
<doing some stuff with content>
return
except IOError:
pass
print("File not found")