2014-06-13 5 views
6

Gibt es eine sauberere Möglichkeit, einige Teile einer URL in Python 2 zu ändern?Ändern von URL-Komponenten in Python 2

Zum Beispiel

http://foo/bar -> http://foo/yah 

Derzeit Ich tue dies:

import urlparse 

url = 'http://foo/bar' 

# Modify path component of URL from 'bar' to 'yah' 
# Use nasty convert-to-list hack due to urlparse.ParseResult being immutable 
parts = list(urlparse.urlparse(url)) 
parts[2] = 'yah' 

url = urlparse.urlunparse(parts) 

Gibt es eine saubere Lösung?

+0

Was genau meinen Sie mit "sauber"? –

Antwort

16

Leider ist die Dokumentation veraltet; Die von urlparse.urlparse() (und urlparse.urlsplit()) erzeugten Ergebnisse verwenden eine collections.namedtuple()-produced class als Basis.

Sie diese namedtuple in eine Liste nicht drehen, aber nur für diese Aufgabe zur Verfügung gestellt Verwendung des Utility-Methode machen:

parts = urlparse.urlparse(url) 
parts = parts._replace(path='yah') 

url = parts.geturl() 

Die namedtuple._replace() method ermöglicht Ihnen das Erstellen Sie eine neue Kopie mit spezifischen Elemente ersetzt. Die ParseResult.geturl() method verbindet die Teile dann wieder in eine URL für Sie.

Demo:

>>> import urlparse 
>>> url = 'http://foo/bar' 
>>> parts = urlparse.urlparse(url) 
>>> parts = parts._replace(path='yah') 
>>> parts.geturl() 
'http://foo/yah' 

mgilson reichte ein bug report (with patch) die Dokumentation Problem zu beheben.

+0

Ich wollte darauf hinweisen. Die Hilfsmethoden werden für "urlparse.ParseResult" durch die von 'namedtuple' zurückgegebene Unterklasse bereitgestellt. Ich denke, dass dies in den 2.7 Dokumenten erwähnt werden sollte, denn ohne das zu wissen, haben Sie keine Möglichkeit zu wissen, dass "_replace" tatsächlich Teil der öffentlichen API für diese Klasse ist ... – mgilson

+0

Noch interessanter ist die Erwähnung von [ 'BaseResult'] (https://docs.python.org/2/library/urlparse.html#urlparse.BaseResult) in den Dokumenten, die überhaupt nicht in der Quelle erscheinen ... (Entschuldigung wegen des Exkurses .. Es ist spät ... +1 sowieso) – mgilson

+0

@mgilson: heh, in der Tat, das muss ein Rest sein, bevor 'namedtuple' verwendet wurde. –

-1

Ich denke, der richtige Weg, um es zu tun ist dieser Weg.

Verwendung von _replace private Methoden oder Variablen wird nicht empfohlen.

from urlparse import urlparse, urlunparse 

res = urlparse('http://www.goog.com:80/this/is/path/;param=paramval?q=val&foo=bar#hash') 
l_res = list(res) 
# this willhave ['http', 'www.goog.com:80', '/this/is/path/', 'param=paramval', 'q=val&foo=bar', 'hash'] 
l_res[2] = '/new/path' 
urlunparse(l_res) 
# outputs 'http://www.goog.com:80/new/path;param=paramval?q=val&foo=bar#hash' 
+1

Es ist Teil der öffentlichen Schnittstelle, es ist nur mit Unterstrich vorangestellt, um nicht mit tatsächlichen Mitgliedern zu kollidieren. – vidstige