Instanzierungsproblem?

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
aga
User
Beiträge: 18
Registriert: Montag 12. März 2007, 15:36

Hi!

Ich würde gerne folgendes realisieren: es gibt einen generischen Wrapper, um Hardware anzusprechen; der hat solche Funktionen wie ping, telnet, ssh, etc. die auch simuliert werden können (abhängig von einem Schalter in der Klasse, den man von aussen zur Laufzeit umlegen kann). In einem anderen Verzeichnis (projektX) liegen projektspezifische Erweiterungen, die von GenericWrapper abgeleitet sind, die auch Dinge wie getKernelVersion, getSoftwareVersion etc, die von Projekt zu Projekt unterschiedlich sind, enthalten.
Beim Booten meiner Applikation wird erst mal festgestellt, welches Projekt bearbeitet werden soll und ob eine Simulation gefahren werden soll oder mit der "echten Hardware" kommuniziert werden soll. Dementsprechend soll das passende Modul (z.B. projektXWrapper aus dem Unterverzeichnis projektX) geladen werden und ab jetzt verwendet werden. Zur Laufzeit soll man zwischen Simulation und echter HW umschalten können.

Der GenericWrapper benutzt seinerseits einen GenericSimulator und GenericConnector, die wiederum Basisklassen für projektspezifische Erweiterungen sind.

soweit die Theorie - jetzt zum Code:

Code: Alles auswählen

import sys,os

def create_instance(*args, **kwargs): 
    module, class_ = args[:2] 
    cls = getattr(__import__(module, None, None, ['']), class_) 
    return cls(*args[2:], **kwargs) 

def re_import(module_name): 
    result = sys.modules.get(module_name) 
    if result is None: 
        result = __import__(module_name) 
    else: 
        reload(result)

class GenericWrapper:
    
    def __init__(self, simMode="OFF", projectPrefix = "projektX"):
        self.simulationMode = simMode
        self.projectPrefix  = projectPrefix
        self.executor = None
        if self.simulationMode == "ON" :
            # executor = simulator class, not yet implemented
            #self.executor = re_import(self.projectPrefix + "Simulator")
            print "simulation mode"
        else:
            # executor = connector to real HW, not yet implemented
            #self.executor = re_import(self.projectPrefix + "Connector")
            print "connection mode"
            
    def pingIt(self):
        self.executor.pingIt()

if __name__ == '__main__':
	    
        topdir = os.getcwd()   
        projektExtension = "projektX" 
        addToPath = os.path.join(topdir,projektExtension)       
        sys.path.append(addToPath)
        print "instantiating projetXWrapper"
        
        nw = create_instance(projektExtension + "Wrapper", projektExtension + "Wrapper", simMode="OFF", projectPrefix = "projektX")
      

und

Code: Alles auswählen

import GenericWrapper


class projektXWrapper(GenericWrapper):
    
    def __init__(self, simMode="OFF", projectPrefix = "projektX"):
        GenericWrapper.__init__(self, simMode, projectPrefix)
        if self.simulationMode == "ON" :
            self.executorName = "projektXSimulator"
        else:
            self.executorName = "projektXConnector"
        
        print "self.executorName = "  + self.executorName    
        

und wenn man dan GenericWrapper.py ausführt, dann bekomm ich diese Fehlermeldung, die ich nicht verstehe (vielleicht aber auch nur vernagelt...)

Code: Alles auswählen

initialising GenericWrapper
Traceback (most recent call last):
  File "F:\tcommander\0.4.4\tests\trial\1\GenericWrapper.py", line 41, in <module>
    nw = create_instance(projektExtension + "Wrapper", projektExtension + "Wrapper", simMode="OFF", projectPrefix = "projektX")
  File "F:\tcommander\0.4.4\tests\trial\1\GenericWrapper.py", line 5, in create_instance
    cls = getattr(__import__(module, None, None, ['']), class_)
  File "F:\tcommander\0.4.4\tests\trial\1\projektX\projektXWrapper.py", line 4, in <module>
    class projektXWrapper(GenericWrapper):
TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)
Hat da jemand eine Idee?

danke im voraus
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

aga hat geschrieben:Hat da jemand eine Idee?
Ja. Du musst den Aufruf von ``__init__`` in Zeile acht ohne ``self`` machen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hi,
aga hat geschrieben:Hat da jemand eine Idee?
ja.

Code: Alles auswählen

import GenericWrapper
class projektXWrapper(GenericWrapper.GenericWrapper):
    def __init__(self, simMode="OFF", projectPrefix = "projektX"):
        GenericWrapper.GenericWrapper.__init__(self, simMode, projectPrefix)
         #....
Gruss
pyStyler
aga
User
Beiträge: 18
Registriert: Montag 12. März 2007, 15:36

Hallo!

Thx, pyStyler, jetzt funkt's - kannst Du bitte einem unbedarften wie mir noch erklären wieso das so zu sein hat????

:?
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

so wird die Klasse "GenericWrapper" direkt in den Namensraum eingebunden ( verfügbar gemacht ).
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Hallo
hab das gleiche Problem und muss sagen das ich die Lösung in diesem Thread nicht verstanden habe...
Ich habe im Moment mal die ganzen anderen Variablen und Methode die nicht dazu beitragen rausgeworfen, normalerweise sind die Klassen nicht so leer....

Ich denke das Problem ist, das ich verschiedene Dateien verwende und so falsch importiere....

Code: Alles auswählen

dejungma@linuxlaptop ~/ $ cat WebInterface.py
#!/usr/bin/python

import Query
import Pdb

class WebInterface(object):
        def __init__(self):
                print "WebInterface wurde erstellt"

def main():
        test = WebInterface()
        test2 = Query.Query()
        test3 = Pdb.Pdb()

if __name__ == '__main__':
        main()




dejungma@linuxlaptop ~/ $ cat Query.py
#!/usr/bin/python


class Query(object):
        def __init__(self):
                print "Query wurde eben erstellt"



dejungma@linuxlaptop ~/ $ cat Pdb.py
#!/usr/bin/python

import Query

class Pdb(Query):
        def __init__(self):
                Query.Query.__init__()   # an der Stelle schon MIT und OHNE self versucht, kein Erfolg
                print "Pdb wurde erstellt"

würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Hab meinen Code jetzt auf ein Minimum reduziert, aber irgendwie kann ich da jetzt keinen Fehler entdecken...

Lese schon die ganze Zeit doc's zum Thema Module und OOP, aber ich sehe nicht was ich falsch mache....

Vielleicht erbarmt sich nochmal jemand über meinen Code zu schauen
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

In Pdb.py erbst du vom Modul und nicht von der Klasse. Das kann ja nicht so funktionieren wie du dir das vorstellst. In Pdb.Pdb.__init__ muss das self natürlich rein (da habe ich irgendeinen Quatsch verzählt). Daher ist es nicht unbedingt schlau, das Modul wie die darin enthaltene Klasse zu benennen - Python ist auch kein Java, dass das nötig wäre.

Außerdem: halte dich an PEP8! Deinen Code sinnvoll einzurücken hat länger gedauert, als den Fehler zu finden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
midan23
User
Beiträge: 147
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Dann will ich mal ...

Wenn ich mir deinen Code anschaue, sehe ich ein Modul Query welches eine Klasse Query enthält.

Um eine Klasse von der Klasse Query abzuleiten hast du zwei Möglichkeiten:

1)

Code: Alles auswählen

from Query import Query

class SubQuery(Query):

    def __init__(self):
        Query.__init__(self)
        print "Done..."
2)

Code: Alles auswählen

import Query

class SubQuery(Query.Query):

    def __init__(self):
        Query.Query.__init__(self)
        print "Done ..."
Ich hoffe, das hilft dir weiter ...

edit: Ein klein wenig zu spät ...
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Ok, ich denk jetzt hab ich es gerafft...

Ich dachte immer mit dem import modulname würde ich eine klasse einbinden und könnte dann auf die methoden zugreifen... zb

import MySQLdb
und dann ein MySQLdb.cursor()

dabei ist es aber so das ich das Modul einbinde und darin die Klasse cursor, also den konstruktor davon aufrufe.....

und wenn ich jetzt hingehe und sage from MySQLdb import *
dann wäre cursor() direkt verfügbar und das kann zu namensproblemen führen... desswegen soll man das mit dem import * nicht machen...

die ganzen scripte die ich hier als "vorlage" von meiner arbeitsgruppe habe sind leider mit import * geschrieben, ich denke dann mal eher ein schlechtes beispiel...

ich hoffe mal ich hab es jetzt richtig interpretiert, zumindest scheint es jetzt zu gehen...
danke für die hilfe...


EDIT: Gerade am PEP8 lesen, hab das vorher nicht gewusst und meinen VI schon angepasst
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

würmchen hat geschrieben:und wenn ich jetzt hingehe und sage from MySQLdb import *
dann wäre cursor() direkt verfügbar und das kann zu namensproblemen führen... desswegen soll man das mit dem import * nicht machen...
Noch dazu kommt es damit zu verständnisproblemen, weil man unter Umständen einfach nicht weiß, wo besteimmte Namen herkommen, von wo sie importiert sidn.
würmchen hat geschrieben:die ganzen scripte die ich hier als "vorlage" von meiner arbeitsgruppe habe sind leider mit import * geschrieben, ich denke dann mal eher ein schlechtes beispiel...
Ja, wir kämpfen schon seit Jahren mit solchen schlechten Beispielen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Ok, nach dem ich dachte, ich habe es verstanden, stoße ich auf neue Probleme...

Hier mal die Fehlermeldung von cgitb:
/var/www/localhost/cgi-bin/pdbkey.py
8 import cgi
9
10 import query
11
12 import cgitb
query undefined
/var/www/localhost/cgi-bin/query.py
2 import webinterface
3
4
5
6 ###############################################################################
webinterface undefined
/var/www/localhost/cgi-bin/webinterface.py
6 import cgi
7
8 import pdbkey
9 import query
10
pdbkey undefined
/var/www/localhost/cgi-bin/pdbkey.py
14
15
16 class PdbKey(query.Query):
17 def __init__(self):
18 #print "pdbkey is created"
PdbKey undefined, query = None, query.Query undefined

AttributeError: 'module' object has no attribute 'Query'
args = ("'module' object has no attribute 'Query'",)
Ich versteh nicht wo jetzt wieder die Probleme sind. ist es weil ich noch gleiche dateinamen wie Klassennamen habe?

Ich habe irgendwo gelesen das es an import sys liegen könnte und man das auskommentieren müsste... aber ich hab das rausgeworfen, gibt kein import sys mehr...

Hier mal die pythonscripte...

webinterface.py:

Code: Alles auswählen

#!/usr/bin/python

import MySQLdb
import cgi

import pdbkey
import query 


class WebInterface(object):
    def __init__(self):
        self.host = "localhost"
        self.database = "bif_1107"
        self.user = "dejungma"
        self.passwd = ""

        try:
            self.db = MySQLdb.connect(host=self.host, user=self.user, \
                                      db=self.database, passwd=self.passwd)
            self.cur = self.db.cursor()
        except MySQLdb.Error:
            self.cur = None
            raise "Error opening the database"

    def askDb(self, query="", value=""):
        self.query = query
        self.value = value
        try:
            self.cur.execute(self.query)
            self.result = self.cur.fetchall()
        except MySQLdb.Error:
            raise "Error calling the database"
        return self.result


def main():
    test = pdbkey.PdbKey()
    test.doEvaluation(query="1%")


if __name__ == '__main__':
    main()
query.py:

Code: Alles auswählen

#!/usr/bin/python
import webinterface  

class Query(object):
    def __init__(self): 
        self.conn = webinterface.WebInterface()



pdbkey.py:

Code: Alles auswählen

#!/usr/bin/python

import cgi
import sys

import query 

import cgitb
cgitb.enable()


class PdbKey(query.Query):
    def __init__(self):
        query.Query.__init__(self)


    def doEvaluation(self, query=""):
        print 'Content-Type: text/html\n'
        self.result = self.conn.askDb('SELECT id,entry_key FROM MMS_ENTRY \
                                      WHERE id LIKE "%s"' % (query, ))
        print len(self.result), " Entry's."


def main(argv):
    evaluation = PdbKey()
    form = cgi.FieldStorage()
    evaluate = form.getvalue('evaluate')
    query = form.getvalue('query')
    if evaluate:
        evaluation.doEvaluation(query)


if __name__ == '__main__':
    main(sys.argv)
Ich hoffe auch das es jetzt PEP8 conform ist...
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

wollte noch dazu sagen, das das programm läuft, wenn ich webinterface.py ausführe, aber nicht wenn ich pdbkey.py ausführe...

wo ist da mein denkfehler...

ich habe die pdbkey.py eben so abgeändert, das sie ohne cgi auskommt und mit bekannten variablen arbeitet...

ich bin total überfragt
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Ich hab das Problem mittlerweile gelöst, aber ich kann es mir nicht erklären...

es funktioniert alles, wenn ich in meine Datei pdbkey.py noch ein
import pdbkey
schreibe... komischerweise muss es auch noch vor dem import query stehen...

kann mir jemand erklären, wiso ich die datei selbst nochmal importieren muss?
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Kann sich das hier keiner erklären? :?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Vermutung: deine CGI-Umgebung ist keine CGI-Umgebung sondern wird von mod_python simuliert und mod_python hat Caching-Probleme so dass die Datei erst neu geladen wurde, als du das Skript verändert hast.

Könnte natürlich auch etwas ganz anderes sein.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

ok, also liegt es jetzt nicht nochmal an verständnisproblemen?....

Wenn ich in so nem Falle den Apache einfach mal neu starte müsste das doch dann neu in den cache geladen werden, oder?

komisch ist aber das ich das ganze eigentlich aus der shell aufrufe und da ja kein Problem mit mod_python sein sollte...

hm, ich importier die jetzt einfach mal immer, sollte ja kein fehler sein...
Antworten