Как я могу разделить строку URL на отдельные части в Python?

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


Во-первых, есть еще некоторые предварительно созданные такие как пустые tuple, str и bytes и некоторые короткие строки (в CPython 3.6 это 256 односимвольных строк Latin-1). Например:

>>> a = ()
>>> b = ()
>>> a is b
True

Но также даже не созданные заранее значения могут быть одинаковыми. Рассмотрим следующие примеры:

>>> c = 257
>>> d = 257
>>> c is d
False
>>> e, f = 258, 258
>>> e is f
True

И это не ограничено значениями int:

>>> g, h = 42.23e100, 42.23e100
>>> g is h
True

Очевидно, что CPython не поставляется с предварительно созданным float для параметра 42.23e100. Итак, что здесь происходит?

Компилятор CPython будет объединять постоянные значения некоторых известных неизменяемых типов, таких как int, float, str, bytes, в одном модуле компиляции. Для модуля весь модуль является единицей компиляции, но в интерактивном интерпретаторе каждый оператор представляет собой отдельный блок компиляции. Поскольку c и d определены в отдельных утверждениях, их значения не объединяются. Поскольку e и f определены в том же самом заявлении, их значения сливаются.


Вы можете видеть, что происходит, разобрав байт-код. Попробуйте определить функцию, которая выполняет e, f = 128, 128, а затем называет dis.dis на ней, и вы увидите, что существует одно постоянное значение (128, 128)

>>> def f(): i, j = 258, 258
>>> dis.dis(f)
  1           0 LOAD_CONST               2 ((128, 128))
              2 UNPACK_SEQUENCE          2
              4 STORE_FAST               0 (i)
              6 STORE_FAST               1 (j)
              8 LOAD_CONST               0 (None)
             10 RETURN_VALUE
>>> f.__code__.co_consts
(None, 128, (128, 128))
>>> id(f.__code__.co_consts[1], f.__code__.co_consts[2][0], f.__code__.co_consts[2][1])
4305296480, 4305296480, 4305296480

. Вы можете заметить, что компилятор сохранил 128 как константу, даже если он фактически не используется байтовым кодом, что дает вам представление о том, как мало оптимизирует компилятор CPython. Это означает, что (непустые) кортежи на самом деле не сливаются:

>>> k, l = (1, 2), (1, 2)
>>> k is l
False

Поместите это в функцию, dis, и посмотрите на co_consts - есть 1 и 2, два (1, 2) кортежа, которые имеют одинаковые 1 и 2, но не идентичны, и кортеж ((1, 2), (1, 2)), который имеет два разных одинаковых кортежа.


Есть еще одна оптимизация, которую выполняет CPython: string interning. В отличие от сгибания константы компилятора, это не ограничивается литералами исходного кода:

>>> m = 'abc'
>>> n = 'abc'
>>> m is n
True

С другой стороны, он ограничен типом str и строками типа внутреннего хранилища «ascii compact», «compact» или «legacy ready» , и во многих случаях только «ascii compact» будет интернирован.


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

Возможно, стоит изучить правила для одного конкретного Python для удовольствия. Но не стоит полагаться на них в вашем коде. Единственное безопасное правило:

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

Или, другими словами, использовать is только для проверки документированных синглетов (например, None) или которые создаются только в одном месте в код (например, идиома _sentinel = object()).

13
задан mmcdole 16 January 2009 в 08:30
поделиться

4 ответа

urlparse модуль в Python 2.x (или urllib.parse в Python 3.x) был бы способом сделать это.

>>> from urllib.parse import urlparse
>>> url = 'http://example.com/random/folder/path.html'
>>> parse_object = urlparse(url)
>>> parse_object.netloc
'example.com'
>>> parse_object.path
'/random/folder/path.html'
>>> parse_object.scheme
'http'
>>>

, Если Вы хотели сделать больше работы над путем файла под URL, можно использовать posixpath модуль:

>>> from posixpath import basename, dirname
>>> basename(parse_object.path)
'path.html'
>>> dirname(parse_object.path)
'/random/folder'

После этого, можно использовать posixpath.join для склеивания частей.

РЕДАКТИРОВАНИЕ: Я полностью забыл, что пользователи Windows будут дросселировать на разделителе пути в os.path. Я прочитал posixpath документы модуля, и это имеет специальную ссылку на управление URL, таким образом, все хорошо.

51
ответ дан 1 December 2019 в 05:49
поделиться

У меня нет опыта с Python, но я нашел urlparse модуль , который должен сделать задание.

10
ответ дан 1 December 2019 в 05:49
поделиться

Если это будет степенью Вашего парсинга URL, то встроенный rpartition Python сделает задание:

>>> URL = "http://example.com/random/folder/path.html"
>>> Segments = URL.rpartition('/')
>>> Segments[0]
'http://example.com/random/folder'
>>> Segments[2]
'path.html'

От Pydoc, str.rpartition:

Splits the string at the last occurrence of sep, and returns a 3-tuple containing the part before the separator, the separator itself, and the part after the separator. If the separator is not found, return a 3-tuple containing two empty strings, followed by the string itself

то, Что это означает, - то, что rpartition делает поиск Вас и разделяет строку в последнем (право больше всего) возникновение символа, который Вы указываете (в этом случае/). Это возвращает кортеж, содержащий:

(everything to the left of char , the character itself , everything to the right of char)
11
ответ дан 1 December 2019 в 05:49
поделиться

В Python много операций сделано с помощью списков. urlparse модуль, упомянутый Sebasian Dietz, может решить Вашу определенную проблему, но если Вы обычно интересуетесь Pythonic способы найти, что наклонные черты в строках, например, пробуют что-то вроде этого:

url = 'http://example.com/random/folder/path.html'
# Create a list of each bit between slashes
slashparts = url.split('/')
# Now join back the first three sections 'http:', '' and 'example.com'
basename = '/'.join(slashparts[:3]) + '/'
# All except the last one
dirname = '/'.join(slashparts[:-1]) + '/'
print 'slashparts = %s' % slashparts
print 'basename = %s' % basename
print 'dirname = %s' % dirname

вывод этой программы - это:

slashparts = ['http:', '', 'example.com', 'random', 'folder', 'path.html']
basename = http://example.com/
dirname = http://example.com/random/folder/

интересные биты split, join, массив нотации части [A:B] (включая отрицательные стороны для offsets-from-the-end) и, в качестве награды, % оператор на строках для предоставления форматирования printf-стиля.

8
ответ дан 1 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: