Anfänger Script läuft auf Konsole - alleine jedoch nicht

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
sadway
User
Beiträge: 12
Registriert: Sonntag 22. Juli 2007, 16:41

Sonntag 22. Juli 2007, 17:02

Hallo miteinander!

Ich bin leider noch Anfänger in Sachen Python. Heute Nachmittag habe ich versucht ein kleines Programm zu schreiben, das aus dem Quelltext einer Webseite Links herausfiltert.
Das funktioniert auch eigentlich ganz gut. Nur wenn ich das Programm mit einem Doppelklick starte (unter Linux - Ubuntu) kommt ja immer die Abfrage "Wollen Sie »rapid« ausführen oder Ihren Inhalt anzeigen lassen?".
Wenn ich nun auf "im Terminal ausführen" klicke funktioniert alles. Klicke ich jedoch nur auf "Ausführen" startet zwar das Programm - jedoch wird nichts in die Datei geschrieben.

Vielleicht kann mir jemand das Verhalten erklären? Braucht Python die Konsole um mit Dateien zu arbeiten?

Da das mein erstes (halbwegs sinnvolles) Programm ist würde es mich auch freuen, wenn Ihr mir vielleicht noch ein paar Tipps geben könntet - was würdet Ihr anderes machen? Oder wo habe ich schlimme Fehler gemacht usw.
Könnte man das mit der Zwischenablage auch mit TK lösen? (Habe leider nichts gefunden.) Gibt es eine elegantere Lösung für das suchen?

Vielen Dank!

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import gtk
import os
from Tkinter import *
import tkMessageBox 

class Rapid:
	def clipboard(self):
		""" Liefert die Links aus Zwischenablage."""
		
		global filelist 
		filelist = []
		
		clipboard = gtk.clipboard_get() # Liest die Zwischenablage aus
		text = clipboard.wait_for_text() 
		
		for text in text.splitlines(): # Zeilenweise verarbeitung
			sr = text.find('http://rapidshare.com/files/') # Findet die Anfangsposition
			er = text.find('.%s' %(filetype)) 
			if sr > 0:
				filelist.append(text[sr:er+4]) # Fügt den Link in die Liste filelist
		if verbose: 
			print 'Zwischenablage kopiert'

	def savefile(self):
		"""Speichert die Ergebnisse in einer Datei."""
		
		global alreadyopen 
		if alreadyopen:	
			f = file(conf_file, 'a')
		else:
			f = file(conf_file, 'w')
		alreadyopen = True
		
		for ding in filelist:
			f.write(ding)
			f.write(os.linesep)
			
		if verbose:
			print '%d Elemente in die Datei %s/%s geschrieben' %(len(filelist), os.getcwd(), conf_file)
		
class App:

	def __init__(self, master):

        	frame = Frame(master)
	        frame.pack()

	        self.button = Button(frame, text="Beenden", fg="red", command=frame.quit)
	        self.button.pack(side=RIGHT)

	        self.get_cache = Button(frame, text="Zwischenablage Kopieren und speichern", command=self.clipboard_save)
	        self.get_cache.pack(side=LEFT)
	        

	def clipboard_save(self):
		rapid.clipboard()
		rapid.savefile()
		
		
global alreadyopen
			
#<config>
verbose = True 			# True|False Gibt an, ob die Aktion auf der Konsole dokumentiert werden soll.
conf_file = 'dl.txt' 		# Dateiname zum Speichern der Links
filetype = "rar" 		# Art der Dateien die Freigestellt werden soll. 
alreadyopen = False 		# True|False Soll die Datei jedesmal überschrieben werden?
#</config>


rapid = Rapid()

root=Tk()
root.title("Rapidshare Linkfreisteller")

app = App(root)
root.mainloop()
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Sonntag 22. Juli 2007, 17:07

Markier die Datei doch als ausführbar mit chmod -x ...

Und dann schau mal, was passiert.
sadway
User
Beiträge: 12
Registriert: Sonntag 22. Juli 2007, 16:41

Sonntag 22. Juli 2007, 17:15

BlackVivi hat geschrieben:Markier die Datei doch als ausführbar mit chmod -x ...
Du meinst wohl mit chmod +x ...aber das ist nicht das Problem, die Datei wird ja ausgeführt.

Nur wenn ich Sie nicht mit auf der Konsole laufen lasse d.h. in meinen Terminal ./rapid eingeben bzw. auf "ausführen im Terminal" klicke werden die Links nicht in die Datei dl.txt geschrieben.

Aber schon mal vielen Dank für deine schnelle Antwort.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Sonntag 22. Juli 2007, 17:33

Wenn ich es mit chmod als ausführbar markier', funktioniert dein Script ohne Probleme, auch ohne Terminal...

Bei Linux haben wohl nur Programme mit diesem Attribut tatsächliche Schreibrechte, ansonsten wird's ihnen wohl verwehrt. Wenn du es mit der Konsole ausführst, wird ja python als intepretierer genommen, der sehr wohl Schreibrechte hat oO... Das wäre zumindest' meine logische Erklärung. Warscheinlich irr ich mich...
sadway
User
Beiträge: 12
Registriert: Sonntag 22. Juli 2007, 16:41

Sonntag 22. Juli 2007, 18:18

Ich denke ich habe das Problem gefunden?!

Ich habe jetzt mal die Statusmeldungen auf der Konsole abgestellt.
Und siehe da es scheint zu funktionieren.

Mit Statusmeldungen meine ich diese hier:

Code: Alles auswählen

verbose = False             # True|False Gibt an, ob die Aktion auf der Konsole dokumentiert werden soll.

        if verbose:
            print 'Zwischenablage kopiert'


        if verbose:
            print '%d Elemente in die Datei %s/%s geschrieben' %(len(filelist), os.getcwd(), conf_file)

Erklären kann ich das nicht ... vielleicht kann es ja jemand von euch :)

Vielen Dank!
BlackJack

Sonntag 22. Juli 2007, 19:02

Ich würde es einfach mal darauf schieben, dass zwei GUI-Toolkits im gleichen Programm benutzt werden.

Das Programm sieht ein bisschen chaotisch aus. Die Klassen sind so nicht sinnvoll. Insbesondere `Rapid` macht keinen Sinn. Jedenfalls nicht wenn die "Methoden" auf globalen Namen operieren. ``global`` sollte man meiden wo es nur geht und das geht in 99% der Fälle.

Statt `os.linesep` sollte man '\n' in die Datei schreiben. Oder die Datei im Binärmodus öffnen. So wie es jetzt ist, wäre `os.linesep` unter Windows '\r\n' -- da bei Textdateien aber beim Schreiben '\n' durch das Zeilenende der Plattform ersetzt wird, landet letztendlich '\r\r\n' in der Datei.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 22. Juli 2007, 19:20

sadway hat geschrieben:Erklären kann ich das nicht ... vielleicht kann es ja jemand von euch :)
Ich kann jetzt auch nur schätzen. Meine Vermutung ist, dass bei dir ``sys.stdout`` auf irgendetwas gesetzt wird, was kein ``write()`` implementiert und somit eine Exception wirft (also etwa ``None``) die aber da es keine Ausgabe gibt, verworfen wird.

Was du machen kannst ist, ``sys.stdout`` und ``sys.stderr`` in eine Datei zu leiten und schauen was dort rauskommt.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
sadway
User
Beiträge: 12
Registriert: Sonntag 22. Juli 2007, 16:41

Sonntag 22. Juli 2007, 20:47

Ich habe jetzt ein wenig weiter rumprogrammiert und es gerade noch mal mit Ausgaben probiert. Jetzt funktioniert es.
Keine Ahnung was ich geändert habe.

BlackJack hat geschrieben:Das Programm sieht ein bisschen chaotisch aus. Die Klassen sind so nicht sinnvoll. Insbesondere `Rapid` macht keinen Sinn. Jedenfalls nicht wenn die "Methoden" auf globalen Namen operieren. ``global`` sollte man meiden wo es nur geht und das geht in 99% der Fälle.
Naja, das mag daran liegen, das ich noch nicht so ganz den Sinn von Klassen verstanden habe - mir wurde aber schon mal gesagt, das das später von selber kommt.
Wäre es sinnvoller wenn ich die clipboard funktion aus der savefile Funktion aufrufe und dort filelist zurückgeben lasse?
BlackJack hat geschrieben: Statt `os.linesep` sollte man '\n' in die Datei schreiben. Oder die Datei im Binärmodus öffnen. So wie es jetzt ist, wäre `os.linesep` unter Windows '\r\n' -- da bei Textdateien aber beim Schreiben '\n' durch das Zeilenende der Plattform ersetzt wird, landet letztendlich '\r\r\n' in der Datei.
Ok, vielen Dank für den Tip. Das wollte ich eigentlich genau vermeiden. Ich werde es ändern.


Python macht irgendwie süchtig. Sitze jetzt hier schon seit 12Uhr und noch keine Langeweile und man lernt es einfach wahnsinnig schnell.
Kein Vergleich zu C dort habe ich mir mühsamst Grundkenntnisse angeeignet.

Auch ein Lob an dieses Forum - ich hätte nicht gedacht, das ich als Anfänger mit einer seltsamen Frage so schnell so viele Antworten bekomme!

Vielen Dank und weiter so :)

edit: hier mal meine aktuelle version http://nopaste.info/76bf172db7_nl.html

ps: gibt es hier auch einen nopaste service?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 22. Juli 2007, 22:03

sadway hat geschrieben:ps: gibt es hier auch einen nopaste service?
Ja, normalerweise gibt es LodgeIt ist aber leider wieder mal down :(
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Montag 23. Juli 2007, 00:39

@sadway: Den Sinn von Klassen versteht man mit der Zeit, wenn man an Probleme stösst, die sich ohne schlechter lösen lassen, nicht in dem man sie ohne zu wissen warum, verwendet.

Klassen sollen Daten und Funktionen, die logisch zusammengehören zu einem Objekt zusammenfassen. Die Daten sind dabei Attribute auf dem Objekt. Wenn man also "Methoden" hat, die gar nicht auf Daten des Objekts zugreifen, dann sind das keine "echten" Methoden.
Antworten