Подтвердить что ты не робот

Преимущества os.path.splitext над регулярным .split?

В этот другой вопрос, голоса ясно показывают, что функция os.path.splitext предпочтительнее простой манипуляции с строкой .split('.')[-1]. У кого-нибудь есть момент, чтобы точно объяснить, почему это так? Это быстрее или точнее, или что? Я готов согласиться с тем, что там что-то лучше, но я не могу сразу понять, что это может быть. Можете ли импортировать целый модуль, чтобы сделать это, переполнять, по крайней мере, в простых случаях?

EDIT: Специфичность ОС - большая победа, которая не сразу очевидна; но даже я должен был увидеть случай "что, если нет точки"! И спасибо всем за общие комментарии к использованию библиотеки.

4b9b3361

Ответ 1

Ну, есть отдельные реализации для отдельных операционных систем. Это означает, что если логика для извлечения расширения файла отличается от Mac от Linux, это различие будет решаться этими вещами. Я не знаю такого различия, чтобы его не было.


Изменить: @Brian, что пример типа /directory.ext/file, конечно, не будет работать с простым вызовом .split('.'), и вам нужно будет знать, что эти каталоги могут использовать расширения, а также тот факт, что в некоторых операционных системах косая черта является допустимым разделителем директорий.

Это просто подчеркивает использование библиотечной процедуры, если у вас нет веской причины не расставаться с моим ответом.

Спасибо @Brian.


Кроме того, если файл не имеет расширения, вам придется построить логику для обработки этого случая. И что, если вещь, которую вы пытаетесь разбить, - это имя каталога, заканчивающееся обратным слэшем? Нет имени файла или расширения.

Правило должно быть таким, что, если у вас нет конкретной причины не использовать библиотечную функцию, которая делает то, что вы хотите, используйте ее. Это позволит избежать необходимости поддерживать и исправлять код, у которого другие имеют отличные решения.

Ответ 2

os.path.splitext корректно обрабатывает ситуацию, когда файл не имеет расширения и возвращает пустую строку..split вернет имя файла.

Ответ 3

splitext() выполняет обратный поиск для '.' и возвращает часть расширения, как только она ее обнаружит. split('.') выполнит прямой поиск всех. и поэтому почти всегда медленнее. Другими словами, splitext() специально написан для возврата расширения в отличие от split().

(см. posixpath.py в источнике Python, если вы хотите изучить реализацию).

Ответ 4

Существуют операционные системы, которые не используют '. как разделитель расширений.

(Примечательно, что RISC OS по соглашению использует "/, поскольку" используется там как разделитель путей.)

Ответ 5

  • Правильный инструмент для правильной работы
  • Уже полностью отлажена и протестирована как часть стандартной библиотеки Python - никаких ошибок, вызванных ошибками в вашей ручной версии (например, что, если нет расширения, или файл является скрытым файлом в UNIX, например ".bashrc", или есть несколько расширений?)
  • Для этой цели функция имеет полезные возвращаемые значения (basename, ext) для переданного имени файла, что может быть более полезным в некоторых случаях, а также необходимость разбить путь вручную (опять же, краевые случаи могут быть проблемой, когда выяснение basename - ext)

Единственная причина беспокоиться об импорте модуля - это беспокойство по поводу накладных расходов - что вряд ли будет проблемой в подавляющем большинстве случаев, и если это так сложно, то, скорее всего, другие накладные расходы на Python станут более серьезной проблемой перед что.

Ответ 6

Четко определенный и документированный способ получения расширения файла всегда будет предпочтительнее, чем разделение строки willy nilly, потому что этот метод будет более хрупким по разным причинам.

Изменить: это не зависит от языка.

Ответ 7

Первое и самое очевидное отличие состоит в том, что раздельный вызов не имеет логики в нем по умолчанию, когда нет расширения.

Это также может быть выполнено с помощью регулярного выражения, чтобы заставить его вести себя как 1 лайнер без дополнительных включений, но все равно возвращать пустую строку, если расширение не существует.

Кроме того, библиотека путей может обрабатывать различные контексты для путей, имеющих разные разделители для папок.

Ответ 8

В комментарии к ответу, который предоставил это решение:

"Если файл не имеет расширения, это неверно возвращает имя файла вместо пустой строки."

Не каждый файл имеет расширение.

Ответ 9

Помимо стандартного и, следовательно, гарантированного наличия, os.path.splitext:

Обрабатывает граничные случаи - как и недостающее расширение.
Предоставляет гарантии. Помимо правильного возврата расширения, если он существует, он гарантирует, что root + ext всегда вернет полный путь.
Является кросс-платформенным - в источнике Python на самом деле существует три разные версии os.path, и они вызываются на основе какой операционной системы Python думает, что вы находитесь.
Более читаемый - считайте, что ваша версия требует от пользователей знать, что массивы могут быть проиндексированы с отрицательными номерами.

btw, это не должно быть быстрее.

Ответ 10

1) простой split ('.') [- 1] не будет корректно работать для пути как C:\foo.bar\Makefile, поэтому вам нужно сначала извлечь basename с помощью os.path.basename() и даже в этом случае он не сможет разделить файл без расширения правильно. os.path.splitext сделать это под капотом.

2) Несмотря на то, что os.path.splitext является кросс-платформенным решением, он не идеален. Давайте посмотрим на специальные файлы с ведущей точкой, например..cvsignore,.bzrignore,.hgignore(они очень популярны в некоторых VCS в качестве специальных файлов). os.path.splitext вернет полное имя файла как расширение, хотя для меня это кажется неправильным. Потому что в этом случае имя без расширения пустая строка. Хотя это предполагаемое поведение стандартной библиотеки Python, это может быть не то, что пользователь хочет на самом деле.

Ответ 11

Я не уверен, что Python был перенесен на платформу VMS, но предположив, что он сделал (*):

  • Имена файлов обычно имеют формат: $device-dir-subdir $filename. $type; $version (**)

Надеюсь, вы поймете, что использование метода узкой области, на который влияют только системы, на которые вы выставлены, не является оптимальным для долговременной ремонтопригодности кода, и такая практика особенно вредна для смешивания и сопоставления разрозненных программных компонентов в крупных проектах программного обеспечения.

По существу, в последнем случае вероятность успеха (надежность) сродна

R (T) = 1- (1-Ri) ^ п

и теперь вы можете увидеть, как плохие/неполные реализации программного обеспечения приводят к ошибкам программ. В более широком смысле, портирование программного обеспечения затруднено именно из-за таких ошибок.

(*) hm, googling быстро выявил: https://www.vmspython.org
(**) Проверьте здесь регулярные войны! fooobar.com/info/212528/...