Преимущества os.path.splitext перед обычным .split? - PullRequest
35 голосов
/ 12 февраля 2009

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

РЕДАКТИРОВАТЬ: специфика ОС является большой победой, которая не сразу очевидна; но даже я должен был увидеть дело "что, если нет точки"! И спасибо всем за общие комментарии по использованию библиотеки.

Ответы [ 11 ]

38 голосов
/ 12 февраля 2009

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


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

Это только подчеркивает, что использует библиотечную процедуру, если у вас нет веских причин не часть моего ответа.

Спасибо @Brian.


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

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

14 голосов
/ 12 февраля 2009

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

11 голосов
/ 12 февраля 2009

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

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

6 голосов
/ 12 февраля 2009

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

(Примечательно, что ОС RISC по соглашению использует ‘/’, поскольку в качестве разделителя пути используется ‘.’)

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

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

2 голосов
/ 12 февраля 2009

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

Редактировать: Это не зависит от языка.

1 голос
/ 12 февраля 2009

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

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

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

0 голосов
/ 08 октября 2017

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

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

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

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

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

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

(*) хм, поиск в Google быстро показал: https://www.vmspython.org
(**) Проверьте в регулярных войнах здесь! https://stackoverflow.com/a/4465456/1574494

0 голосов
/ 13 февраля 2009

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

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

0 голосов
/ 12 февраля 2009

Помимо того, что стандартно и поэтому гарантированно будет доступно, os.path.splitext:

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

Кстати, это не должно быть быстрее.

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