Selbstzerstörende Instanz

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
4lb3rtO
User
Beiträge: 3
Registriert: Freitag 7. September 2012, 15:43

Hallo an alle,

ist es möglich eine "Selbstzerstörende Instanz" einer Klasse zu erzeugen? So nach dem Motto:

Code: Alles auswählen

class MeineKlasse():
    x = 'miau'

    def __init__(self):
        print self.x
        self.x = 'wuff'
        self.kill()

    # Irgendwelche weitere Methoden
    # ...
        
    def kill(self): #diese Funktion soll die Instanz der Klasse zerstören
        print self.x
        del self    #?


mk = MeineKlasse()
print mk.x        #Hier müsste dann ja eine fehlermeldung erscheinen (name 'mk' is not defined)
Zum Hintergrund: Ich möchte nur eine Instanz ezeugen, die mehfach aufgerufen werden kann und erst beim Durchlaufen einer bestimmten Methode zerstört/gelöscht werden soll. Ist so etwas in dieser Form überhaupt möglich? Besten Dank im Vorraus

Schöne Grüße
4lb3rtO
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo und willkommen im Forum!

Am besten beschreibst du konkret, was du vor hast. Dein Ansatz ist noch zu abstrakt um sich sinnvoll darüber äußern zu können.

Sebastian
Das Leben ist wie ein Tennisball.
lunar

@4lb3rt In Python kann ein Objekt sich nicht selbst löschen. Python ist nicht C++, und was immer Du vorhast, wenn Du dazu ein sich selbst löschendes Exemplar benötigst, oder auch nur irgendwie Objekte löschen musst, dann ist es der falsche Weg in Python.

Erkläre uns, was Du eigentlich umsetzen möchtest, dann können wir Dir sagen, wie man das in Python vernünftig implementiert.
4lb3rtO
User
Beiträge: 3
Registriert: Freitag 7. September 2012, 15:43

Hallo Sebastian,

ich bin momentan dabei ein kleines Script für das Mediencenter XBMC zu schreiben. Dieses soll nach Ablauf eines Timers verschiedene Aktionen wie z.B ein Fernseher ausschalten, Nas ausschalten, XBMC beenden, den Ruhezustand des Computers einleiten etc. Hierfür werden einfach verschiedene Konsolenbefehle abgesetzt.

Ein paar Anmerkungen zur Arbeitsweise des Scripts:
- Passwort abfragen, welches später für ein ext. Programm gebarucht wird (damit dieses nicht in Klartext im Quellcode steht) [Password]
- Zahlenblock zur Eingabe der Wartezeit öffnen [Password]
- Timer starten [StartTimer]
- Eine Minute vor Ablauf eine Warnung anzeigen (mit Möglichkeit zum Abbruch des Timers, Dauer 1 min) [LastWarning] [CancelActions]
- Nach Ablauf der Minute die Aktionen ausführen [Start Actions]


Ob der Quelltext jetzt gut oder schlecht ist, sei mal dahin gestellt. Hauptsache es funktioniert :D Leider sind meine Python Kenntnisse nicht sonderlich fundiert.
Das Problem besteht nun bei dem Abbruch des laufenden Timers von def StartTimer. Der Zahlenblock (self.StartTimer(dialog.numeric(0, 'Zeit in min', '')) in def Password soll Übergabe eines leeren Strings (keine Zeiteingabe) den Timer abbrechen.

Beispiel:
-Ich rufe das Script auf
-Eine Instanz der Klasse wird ezeugt, das komplette Skript durchlaufen und der Timer arbeitet in XBMC im Hintergrund
-Nun möchte ich beispielsweise den Timer abbrechen (also das script erneut starten)
-Dazu müsste ich ja die bereits erzeugte Instanz wieder aufrufen, einen leeren String mit dem Nummernblock übergeben und die Methode def CancelTimer aufrufen

Hier stehe ich grade irgendwie auf dem Schlauch. Die alte Instanz wieder aufrufen und erst beim Durchlaufen von def CancelActions die Instanz zerstören.

?????

Geht das irgendwie oder ist das alles Banane?

Schönen Gruß
4lb3rtO


Hier noch ein paar Infos zu XBMC

http://wiki.xbmc.org/index.php?title=HO ... text_label
http://xbmc.sourceforge.net/python-docs/


Code: Alles auswählen

import xbmc, xbmcgui, os, time, datetime, threading, hashlib

class MyClass(xbmcgui.WindowDialog):
  pwd = ''
  
  def __init__(self):
    dialog = xbmcgui.Dialog()

    keyboard = xbmc.Keyboard()
    keyboard.setHiddenInput(True)
    keyboard.setHeading('Passwort eingeben')
    keyboard.doModal()

    if (keyboard.isConfirmed()):
        self.pwd = keyboard.getText()
        self.Password(self.pwd)
        


  def Password(self, Passwort):
    #Passwort: pw
    pwhash = 'be196838736ddfd0007dd8b2e8f46f22d440d4c5959925cb49135abc9cdb01e84961aa43dd0ddb6ee59975eb649280d9f44088840af37451828a6412b9b574fc'
    pw = hashlib.sha512(Passwort)

    dialog = xbmcgui.Dialog()
    if pwhash == pw.hexdigest():
      #dialog.ok("Passwort", "Zugriff erlaubt")
      try:
        self.StartTimer(dialog.numeric(0, 'Zeit in min', ''))
      except:
        #dialog.ok("Passwort", "Eingabe abgebrochen")
        exit
    else: 
      dialog.ok("Passwort", "Falsches Passwort. Zugriff verweigert")



  def StartTimer(self, Dauer):
    if Dauer == '':      
      self.CancelActions()
    else:                       
      self.t1 = datetime.datetime.now()
      self.timer = threading.Timer((int(Dauer)-1)*60, self.LastWarning, [self.t1])
      self.timer.start()



  def LastWarning(self, Dauer):
    self.t1 = datetime.datetime.now()    
    self.Thread = threading.Thread(target = self.CancelDialog)
    self.Thread.start()
    self.timer = threading.Timer(60, self.StartActions, [self.t1])
    self.timer.start()



  def CancelDialog(self):
    dialog = xbmcgui.Dialog()
    if dialog.yesno("Achtung", "Ruhezustand in 1 min! Beenden abbrechen?"):      
      self.CancelActions()



  def StartActions(self, Startzeitpunkt):
    dialog = xbmcgui.Dialog()
    dialog.ok("Timer", "Timer ist abgelaufen")

    #os.system('Pfad zur exe -PARAMETER')
    #time.sleep(10)
    #os.system('Pfad zur exe + PARAMETER + self.pwd + ' PARAMETER')
    #time.sleep(10)
    #os.system('shutdown -h')
    #xbmc.shutdown()



  def CancelActions(self):
    dialog = xbmcgui.Dialog()    
    try:
      self.timer.cancel()
      dialog.ok("CancelActions Try", "Timer abgebrochen")
      
      #del self     ################## ??

    except:
      dialog.ok("CancelActions Except", "Timer konnte nicht abgebrochen werden")
      exit


mydisplay = MyClass()
#del mydisplay
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo,

dein Code sieht wirklich sehr konfus aus ;-) Suchst du vielleicht einfach nur die cancel-Methode bei Timern?

Noch ein paar Sachen zum Code, welche mir aufgefallen sind:
- MyClass sollte noch einen richtigen Namen erhalten
- "pwd" braucht nicht an die Klasse gebunden zu werden
- benutze generell richtige Namen; password sagt mehr aus als pwd
- zu einem if gehören keine Klammern
- schau dir mal PEP 8 an, besonders was die Benamung von Funktionen angeht
- du solltestd nicht alles an self binden, bei self.pwd ist das zum Beispiel unnötig
- ein except, was alle Fehlermeldung abfängt ist sehr gefährlich, damit verdeckst du unter Umständen auch Programmierfehler; gib immer die Fehler an, welche du auch behandelst
- exit macht nichts, du meinst exit()
- entscheide dich für Englisch oder Deutsch, beides durcheinander ist nicht besonders leserlich

Sebastian
Das Leben ist wie ein Tennisball.
4lb3rtO
User
Beiträge: 3
Registriert: Freitag 7. September 2012, 15:43

Hallo zusammen,

ich habe den Code mal weitestgehend überarbeitet und Kommentare eingefügt um ihn ein wenig lesbarer zu machen. Um das Problem mal anders zu formulieren. Ich würde gerne das Script einmal starten und durchlaufen, sodass der Timer von "def starte_timer" aktiv ist. Wenn dies der Fall ist habe ich keine Möglichkeit diesen abzubrechen. Daher würde ich gerne das Script erneut starten, einen leeren String bei der Zeiteingabe an "def starte_timer" übergeben und den Timer mit "def timer_abbrechen" abbrechen. Nur erzeuge ich ja beim erneuten Aufruf eine neue Instanz. So habe ich keinen Zugriff auf die alte Instanz und kann den Timer nicht abbrechen.
Hat jemand eine Idee, ob man das irgendwie umgehen kann?

Schöne Grüße
4lb3rtO

Code: Alles auswählen

# -*- coding: cp1252 -*-
import xbmc
import xbmcgui
import os
import time
import datetime
import threading
import hashlib


class Sleeptimer(xbmcgui.WindowDialog):

    Passwort = ''

    # Bildschirmtastatur in XBMC öffenen und Eingabe an "def passwort_pruefen" weiterreichen.
    # Das Passwort wird für ein externes Programm benötigt (in "def aktionen_starten").
    def __init__(self):
        dialog = xbmcgui.Dialog()
        keyboard = xbmc.Keyboard()
        keyboard.setHiddenInput(True)
        keyboard.setHeading('Passwort eingeben')
        keyboard.doModal()
        if keyboard.isConfirmed():
            Passwort = keyboard.getText()
            self.passwort_pruefen(Passwort)
        

    # Passwort mit Hilfe des zuvor erzeugten Hash Wertes überprüfen. Wenn korrekt: Bildschirmnummernblock in XBMC zur Eingabe einer Zeit öffnen.
    # Eingabe an "def start_timer" weitergeben.
    # Try/except für den Fall des Abbruchs der Eingabe in Nummernblock (schließen)
    def passwort_pruefen(self, Passwort):
        dialog = xbmcgui.Dialog()
        #Passwort: pw
        PasswortHash = 'be196838736ddfd0007dd8b2e8f46f22d440d4c5959925cb49135abc9cdb01e84961aa43dd0ddb6ee59975eb649280d9f44088840af37451828a6412b9b574fc'
        Passwort = hashlib.sha512(Passwort)
        
        if PasswortHash == Passwort.hexdigest():
            #dialog.ok("Passwort", "Zugriff erlaubt")
            try:                
                self.starte_timer(dialog.numeric(0, 'Zeit in min', ''))             # Nummernblock
            except:
                #dialog.ok("Passwort", "Eingabe abgebrochen")
                exit()
        else: 
            dialog.ok("Passwort", "Falsches Passwort. Zugriff verweigert.")


    # Timer mit übergebener Zeit starten und bei Ablauf "def letzte_warnung" aufrufen
    def starte_timer(self, Dauer):
        if Dauer == '':
            self.timer_abbrechen()
        else:
            self.timer = threading.Timer((int(Dauer)-1)*60, self.letzte_warnung)            
            self.timer.start()
            

    # Dialog öffnen mit der Möglichkeit den neuen Timer (1 min) abzubrechen und die Ausführung der
    # Aktionen der "def aktionen_starten" zu verhindern.
    # Um nicht auf eine Bestätigung des Dialoges durch den Benutzer angewiesen zu sein und somit den Programm-
    # ablauf zu behindern wird der Dialog in einem Thread gestartet. Der Timer läuft somit im Hintergrund weiter.
    # "def aktionen_starten" und "def dilaog_abbruch" aufrufen.
    def letzte_warnung(self):
        self.Thread = threading.Thread(target = self.dialog_abbruch)
        self.Thread.start()
        self.timer = threading.Timer(60, self.aktionen_starten)        
        self.timer.start()


    # Wenn der Dialog bejaht wird "def timer_abbrechen" aufrufen.
    def dialog_abbruch(self):        
        dialog = xbmcgui.Dialog()
        if dialog.yesno("Achtung", "Ruhezustand in 1 min! Beenden abbrechen?"):      
            self.timer_abbrechen()


    # Verschiedene Aktionen ausführen.
    def aktionen_starten(self):
        #machwas
        #machwas
        #machwas


    # Timer abbrechen und somit die Ausführung der Aktionen in "def aktionen_starten" verhindern.
    def timer_abbrechen(self):
        dialog = xbmcgui.Dialog()    
        try:
            self.timer.cancel()                
            dialog.ok("timer_abbrechen", "Timer abgebrochen")            
        except:
            dialog.ok("timer_abbrechen", "Timer konnte nicht abgebrochen werden")
            exit()


MeinSleeptimer = Sleeptimer()
#del MeinSleeptimer
Antworten