Python Datei zur Wiederverwendung erneut laden

Plattformunabhängige GUIs mit wxWidgets.
Antworten
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Hallo,

ich importiere eine Python-Datei mit funktionalem Code und führe deren Funktion aus. Wenn ich anschließend erneut auf meinen Button klicke, kann ich die Funktion nicht mehr ausführen. So sieht das aus:

Code: Alles auswählen

    
def StartButtonClick(self, event):
        

        if self.startButton.Label == "Start":
            self.startButton.SetLabel("Save recording")
            import pongo 
            
            
        else:
            self.startButton.SetLabel("Start")
            import pongo
            pongo.loop.quit()

Die "pongo.py" (die ich im oberen Teil meiner Ausgangsdatei hole) importiert in deren Kopf wiederum:

Code: Alles auswählen

import pygtk
pygtk.require("2.0")
import gobject
gobject.threads_init()
import pygst
pygst.require("0.10")
import gst

import signal
import subprocess
import os.path
import sys
import re
Wie kann ich nun den Import (in meiner Ausgangsdatei) entladen, sodass ich die Funktion der Datei erneut nutzen kann? Bedanke mich im Voraus für Eure Antworten.
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
BlackJack

@pe: Du scheinst Dich da auf Code zu verlassen, der auf Modulebene von `pongo` ausgeführt wird und willst den *wieder* ausführen? Keine gute Idee. Pack den in eine Funktion und führe die aus. Das kannst Du auch mehrfach machen. Und der Import von `pongo` kann dann auch wie sich das gehört an den Anfang des Moduls mit der `StartButtonClick()`-Methode verschoben werden, damit man dort schon am Anfang sehen kann, wovon dieses Modul abhängt.
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

Also du meinst, ich soll beide Dateien zu einer zusammenführen? Wenn ich den "import pongo" an den Anfang meiner Datei schreibe, so wird die Funktion direkt ausgeführt. Deshalb packe ich den Import bisher in die Funktion.
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.
pe hat geschrieben:Also du meinst, ich soll beide Dateien zu einer zusammenführen? Wenn ich den "import pongo" an den Anfang meiner Datei schreibe, so wird die Funktion direkt ausgeführt. Deshalb packe ich den Import bisher in die Funktion.
Nein, du möchtest das pongo-Modul anpassen. Alles was dort auf der Ebene des Moduls ausgeführt wird, packst du in eine Funktion "funktion". Statt "import pongo" machst du nun den Aufruf "pongo.funktion()".

Sebastian
Das Leben ist wie ein Tennisball.
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

In eine Funktion kann ich den Dateiinhalt m.E. nicht packen, da der Dateiinhalt bereits Funktionen hat. Jetzt ist die Frage, ob es sinnvoll ist eine Klasse zu erstellen. Der Ordnung halber erscheint es mir sinnvoll, Klassen in getrennten Dateien unter zu bringen. Dazu frage ich mich, welchen Unterschied es bei der Ausführung macht, ob die Funktionen in derselben Datei enthalten sind oder in einer anderen.
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
BlackJack

@pe: Du sollst nicht den gesamten Dateiinhalt in eine Funktion packen, sondern den Code auf Modulebene der ausgeführt wird. (Ja ich weiss, dass ``def``\s auch ausgeführt werden, aber die sind natürlich nicht gemeint.)

Klassen und Funktionen "der Ordnung halber" zu trennen ist kein gutes Ordnungskriterium. In Module gehören Sachen, die thematisch zusammengehören. Die Unterscheidung ob ein Objekt Klasse oder Funktion ist, hat damit nichts zu tun, das ist eine rein technische Unterscheidung.
pe
User
Beiträge: 44
Registriert: Dienstag 2. Februar 2010, 18:33

BlackJack hat geschrieben:@pe: Du sollst nicht den gesamten Dateiinhalt in eine Funktion packen, sondern den Code auf Modulebene der ausgeführt wird. (Ja ich weiss, dass ``def``\s auch ausgeführt werden, aber die sind natürlich nicht gemeint.)
Ich verstehe das nicht. So sieht der Inhalt der Datei aus, die vorher mit "import pongo" als Modul herangeschafft wurde:

Code: Alles auswählen

#!/usr/bin/env python
# Pongo, an inexpensive UI lab
# Originally by Andreas Nilsson: http://www.andreasn.se/blog/?p=96
# Requires python and istanbul: http://live.gnome.org/Istanbul


print """
- Default camera video position is bottom right.
  To change, use 'top' and 'left' as arguments.
- Disable camera with 'nocam'.
- If you are conducting a RTA (= retrospective thinking aloud),
  use 'shift' to set the camera video next to the one already there.
- For a custom filename use 'filename.ogv' as argument.
- Reduce output file resolution with the width in pixels as argument.
"""

import pygtk
pygtk.require("2.0")
import gobject
gobject.threads_init()
import pygst
pygst.require("0.10")
import gst

import signal
import subprocess
import os.path
import sys
import re


def clean_shutdown(p):
    camsrc = p.get_by_name("camsrc")
    xsrc = p.get_by_name("xsrc")
    asrc = p.get_by_name("asrc")
    eos = gst.event_new_eos()

    camsrc.send_event(eos)
    xsrc.send_event(eos)
    asrc.send_event(eos)

    bus = p.get_bus()
    bus.poll(gst.MESSAGE_EOS | gst.MESSAGE_ERROR, -1)

def interrupt():
    loop.quit()

# This function takes Bash commands and returns them
# Taken from http://magazine.redhat.com/2008/02/07/python-for-bash-scripters-a-well-kept-secret/
def runBash(cmd):
    p = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE)
    out = p.stdout.read().strip()
    return out


# Recording name
out_file = "recording-"
count = 1
while(os.path.isfile(out_file + str(count) + ".ogv")):
    count = count + 1

out_file += str(count)
out_file += ".ogv"

for arg in sys.argv:
    if re.search(".ogv", arg):
        if(os.path.isfile(arg)):
            print "File %s already exists!" % arg
        else:
            out_file = arg


# Screen dimensions
out_w = int(runBash("xdpyinfo | grep dimensions | cut -d' ' -f7 | cut -d'x' -f1"))
out_h = int(runBash("xdpyinfo | grep dimensions | cut -d' ' -f7 | cut -d'x' -f2"))

for arg in sys.argv:
    if arg.isdigit():
        if int(arg) > out_w:
            print "Can not scale video up!"
        else:
            arg = int(arg)
            out_h = out_h * arg / out_w
            out_w = arg


# Camera video
cam = True
cam_w = 320
cam_h = 240
# TODO: Implement camera video scaling as well
# v4l2src seems to have problems with other values
#cam_w = round(out_w / 4)
#cam_h = round(cam_w * 3/4)
cam_opacity = 0.8
v4l_device = "/dev/video0"
cam_x = out_w - cam_w
cam_y = out_h - cam_h

for arg in sys.argv:
    if arg == "left":
        cam_x = 0
    elif arg == "top":
        cam_y = 0
    elif arg == "nocam":
        cam = False
        cam_opacity = 0 # hack, TODO: deactivate cam directly

for arg in sys.argv:
    if arg == "shift":
        if cam_x == 0:
            cam_x += cam_w
        else:
            cam_x -= cam_w


# Do it!
p = gst.parse_launch("""videomixer name = mix ! ffmpegcolorspace ! queue ! theoraenc ! oggmux name = mux ! filesink location = %s
istximagesrc name = xsrc use-damage = false ! videorate ! video/x-raw-rgb,framerate = 10/1 ! ffmpegcolorspace ! videoscale method = 1 ! video/x-raw-yuv,width = %d,height = %d ! mix.sink_0
v4l2src name = camsrc device = %s ! ffmpegcolorspace ! videorate ! video/x-raw-yuv, framerate = 10/1, width = %d, height = %d ! queue ! videoscale ! ffmpegcolorspace ! video/x-raw-yuv,height = %d,height = %d ! mix.sink_1
alsasrc name = asrc ! queue ! audioconvert ! vorbisenc ! mux.""" % \
    (out_file, out_w, out_h, v4l_device, cam_w, cam_h, cam_w, cam_h))

mix = p.get_by_name("mix")
cam_pad = mix.get_pad("sink_1")
cam_pad.set_property("xpos", cam_x)
cam_pad.set_property("ypos", cam_y)
cam_pad.set_property("alpha", cam_opacity)
cam_pad.set_property("zorder", 1)


p.set_state(gst.STATE_PLAYING)
print "Capturing %sx%s video to %s ..." % (out_w, out_h, out_file)

loop = gobject.MainLoop()
try:
  loop.run()
except KeyboardInterrupt:
  pass 

print "Stopping capture ..."
clean_shutdown(p)
p.set_state(gst.STATE_NULL)
print "Successfully saved as %s" % out_file
(Ja ich weiss, dass ``def``\s auch ausgeführt werden, aber die sind natürlich nicht gemeint.)
Was davon soll ich jetzt auslagern, das nicht in den "def" steht - also keine Funktion ist?
Ich bedanke mich für Eure Zeit und Aufmerksamkeit.
BlackJack

@pe: Genau -- alles was nicht in einer Funktion steht, und selbst keine Funktionsdefinition oder ein ``import`` ist, sollte in eine Funktion gesteckt werden. Und die sollte vielleicht das Objekt was Du später noch einmal zum Stoppen brauchst, als Ergebnis zurückgeben.

Und dass dort `sys.argv` ausgewertet wird, ist natürlich auch ungünstig. Das Modul ist als Modul in der Form ja nicht wirklich gut zu gebrauchen.
Antworten