Seite 1 von 1
Datei aus dem Internet herunterladen (download_file.py)
Verfasst: Montag 25. April 2005, 20:57
von gerold
(Stichworte: http, https, Benutzername, Passwort)
Hi!
Mit diesem kleinen Codeausschnitt kann man eine Datei aus dem Internet herunterladen. Und das funktioniert auch, wenn man dafür einen Benutzernamen und ein Passwort angeben muss.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset: 3 -*-
import urllib2 as __urllib2
import base64 as __base64
#--------------------------------------------------------------
def download_file(url, webuser = None, webpass = None):
"""
Datei aus dem Internet herunterladen
"""
request = __urllib2.Request(url)
if webuser:
base64string = __base64.encodestring('%s:%s' % (webuser, webpass))[:-1]
request.add_header("Authorization", "Basic %s" % base64string)
htmlFile = __urllib2.urlopen(request)
htmlData = htmlFile.read()
htmlFile.close()
return htmlData
#--------------------------------------------------------------
if __name__ == "__main__":
# Test
#*****************************
__url = "http://gerold.bcom.at"
#__webuser = "benutzername"
#__webpass = "passwort"
#print download_file(__url, __webuser, __webpass)
print download_file(__url)
#*****************************
mfg
Gerold
Verfasst: Montag 25. April 2005, 22:21
von BlackJack
Die vielen führenden Unterstriche verwirren mich etwas!?
Verfasst: Montag 25. April 2005, 22:37
von gerold
BlackJack hat geschrieben:Die vielen führenden Unterstriche verwirren mich etwas!?
Hi BlackJack!
Das ist so etwas wie eine Notlösung, damit ich beim Importieren dieses Moduls nicht automatisch auch
urllib2 und
base64 in der Codevervollständigung des WingIDE
http://wingware.com/ habe.
Viel schlimmer ist aber, dass
url,
webuser und
webpass auch aufscheinen würde, wenn ich die Unterstriche nicht machen würde.
Andernfalls hätte ich die Funktion in eine Klasse einschließen müssen und in anderen Programmen müsste ich mit "from download_file import Foo" arbeiten, was mir bei so kurzen Modulen nicht praktikabel erschien.
Ziel: Variablen und Imports des Modules sollen nicht nach außen hin sichtbar sein bzw. nicht unbedingt als PUBLIC erscheinen. Könnte man das anders lösen?
lg
Gerold
Verfasst: Montag 25. April 2005, 22:47
von gerold
gerold hat geschrieben: Ziel: Variablen und Imports des Modules sollen nicht nach außen hin sichtbar sein bzw. nicht unbedingt als PUBLIC erscheinen. Könnte man das anders lösen?
Ich würde ja gerne die Import-Anweisungen direkt in der Funktion machen, aber das gefällt den meisten nicht. Es macht zwar laut meinen Tests keinen messbaren Geschwindigkeitsunterschied, auch wenn ich in einem Modul hunderte Male das selbe Modul importiere, ... es wird ja nicht wirklich neu geladen.
Ich schreibe es mal um. Dann sieht man den Unterschied.
Verfasst: Montag 25. April 2005, 22:52
von gerold
So würde es anders aussehen. Import in der Funktion. Nach außen hin ist nur "download_file" und "modultest" sichtbar.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#--------------------------------------------------------------
def download_file(url, webuser = None, webpass = None):
"""
Downloads a file
"""
import urllib2
import base64
request = urllib2.Request(url)
if webuser:
base64string = base64.encodestring('%s:%s' % (webuser, webpass))[:-1]
request.add_header("Authorization", "Basic %s" % base64string)
htmlFile = urllib2.urlopen(request)
htmlData = htmlFile.read()
htmlFile.close()
return htmlData
#--------------------------------------------------------------
def main():
# Test
#*****************************
url = "http://gerold.bcom.at"
#webuser = "username"
#webpass = "passwort"
#print download_file(url, webuser, webpass)
print download_file(url)
#*****************************
#--------------------------------------------------------------
if __name__ == "__main__":
main()
lg
Gerold
Verfasst: Dienstag 26. April 2005, 22:22
von BlackJack
Bei der Funktion `modultest()` kannst Du die Unterstriche vor den Namen jetzt ja entfernen.
Um sie "pseudo-private" zu machen reicht auch 1 Unterstrich und ich weiss echt nicht warum es so schlimm ist, die importierten Module im Namensraum zu haben. Das ist völlig normal und man sieht das bei sehr vielen Modulen in der Standardbibliothek.
Es scheint, Du versuchst ein "Problem" von Deiner IDE damit zu umgehen.
Verfasst: Dienstag 26. April 2005, 22:54
von gerold
Hi BlackJack
BlackJack hat geschrieben: Bei der Funktion `modultest()` kannst Du die Unterstriche vor den Namen jetzt ja entfernen.
Habe ich soeben erledigt.
BlackJack hat geschrieben: Um sie "pseudo-private" zu machen reicht auch 1 Unterstrich und ich weiss echt nicht warum es so schlimm ist, die importierten Module im Namensraum zu haben. Das ist völlig normal und man sieht das bei sehr vielen Modulen in der Standardbibliothek.
Es scheint, Du versuchst ein "Problem" von Deiner IDE damit zu umgehen.
Wenn ich
import download_file schreibe und später im Code
download_file. (man achte auf den Punkt) eingebe, dann bietet mir WingIDE natürlich alles an, was ich über dieses Modul importiert habe. Das sehe ich jetzt nicht als "Problem" der IDE an, sondern eher als Feature. Dass teilweise wirklich viele Objekte in manchen Namensräumen rumschwirren, sieht man erst so recht, wenn man eine IDE verwendet, die den Namensraum nach verfügbaren Metoden, Variablen, usw. durchsucht.
Der Luxus besteht darin, eine kurze Liste als Hilfe beim Programmieren zu bekommen. Je größer die Liste wird, desto länger braucht man um diese Liste zu durchsuchen --> weniger Luxus
So schlecht ist Kapselung ja auch wieder nicht
Ich denke mal, dass ich mir das wieder angewöhnen werde, die Imports da zu machen wo ich sie brauche und nicht am Anfang des Moduls. Das habe ich mir gegen meine Überzeugung einreden lassen.
lg
Gerold
Verfasst: Mittwoch 27. April 2005, 06:05
von jens
Sollte man in WingIDE nicht dann einbauen, das er generell Python-Basis-Module/Objekte ignoriert?
Verfasst: Mittwoch 27. April 2005, 11:39
von gerold
jens hat geschrieben:Sollte man in WingIDE nicht dann einbauen, das er generell Python-Basis-Module/Objekte ignoriert?
Hi jens!
Aber das Verhalten von WingIDE ist absolut korrekt. Ich habe vom importierenden Modul aus, Zugriff auf die importierten Module des anderen Modules.
meintest.py:
Code: Alles auswählen
import string
my_var = "Ungeaendert"
def show_var():
print "Aufruf aus meintest.py:", my_var
meintest2.py:
Code: Alles auswählen
import meintest
print meintest.string.center("Verwendung von 'string'", 40)
print meintest.my_var
meintest.my_var = "Geaendert"
print meintest.my_var
meintest.show_var()
Ergebnis:
Code: Alles auswählen
Verwendung von 'string'
Ungeaendert
Geaendert
Aufruf aus meintest.py: Geaendert
meintest2.py mit import*:
Code: Alles auswählen
from meintest import *
print string.center("Verwendung von 'string'", 40)
print my_var
my_var = "Geaendert"
print my_var
show_var()
Code: Alles auswählen
Verwendung von 'string'
Ungeaendert
Geaendert
Aufruf aus meintest.py: Ungeaendert
Zumindest wird bei
from meintest import * die Variable
my_var nicht geändert.
Meine Lösung:
- Kein oder wenig Code außerhalb von Funktionen
Ausnahme: if __name__ == "__main__": funktionsaufruf()
- Importiert wird da wo ich es brauche: in Funktionen, in Klassen, aber wenn möglich nicht in der obersten Ebene des Moduls.
So kann ich meine Namensräume sauber halten, was mir auch beim Programmieren ein sicheres Gefühl gibt. Wie ich schon schrieb: Ein wenig mehr Kapselung finde ich nicht schlecht.
lg
Gerold
Verfasst: Mittwoch 27. April 2005, 11:47
von jens
gerold hat geschrieben:
Aber das Verhalten von WingIDE ist absolut korrekt. Ich habe vom importierenden Modul aus, Zugriff auf die importierten Module des anderen Modules.
Das mag ja sein, aber oben hast du dich
beschwert das WingIDE zig Python-eigene-Module anbieten würde... Diese könnte man doch einfach rausfiltern.
*-Imports versuche ich allerdings immer zu vermeiden... Wenn ich mir fremden Code anschaue, ist es manchmal schwirieg festzustellen, wo was herkommt...
Verfasst: Mittwoch 27. April 2005, 12:12
von gerold
jens hat geschrieben: aber oben hast du dich beschwert das WingIDE zig Python-eigene-Module anbieten würde...
Hi Jens!
Sorry, das ist wohl falsch rüber gekommen.
lg
Gerold
Verfasst: Freitag 6. Mai 2005, 21:29
von globox
Ähm sorry aber wo läd er die datei überhapt hin?
Verfasst: Freitag 6. Mai 2005, 22:51
von gerold
globox hat geschrieben:Ähm sorry aber wo läd er die datei überhapt hin?
Hi!
Das mit dem Speichern funktioniert so:
Code: Alles auswählen
import download_file
f = file("xxx.html", "wb")
f.write(download_file.download_file("http://gerold.bcom.at"))
f.close()
mfg
Gerold
Verfasst: Samstag 7. Mai 2005, 00:38
von globox
Ach, hätt ich mir auch denken können
Danke