Seite 1 von 1

perl ruft pyhton auf

Verfasst: Montag 31. Oktober 2005, 10:40
von mr.hide
HAllo,

ich muss folgendes realisieren,
einen querypool der mir je nach argumenten die querys zusammenbaut.

Dies hab ich mit python geschrieben. Läuft auch ganz gut nun soll dieser pool auch über perl erreichbar sein, hab das mal über einen Aufruf der commandline gemacht, bin damit aber nocht nicht ganz zufrieden.

Hat jemand von euch eine Idee?

Code: Alles auswählen

import sys    

class QueryPool:
    """
    If u want to add an new query, just write the name to the caseDict{}
    and add an function with self.getArgs(AmountofArgs)at the start
    and add an return on the end.
    """
    
    ArgList = []
    callByPython = False
    
    def __init__(self, callByPython= False):
        """
        Look if sys.argv[1] exists, then call the function
        """
        self.callByPython = callByPython
        
        if not self.callByPython:
            #sys.argv[1] is the first written argument:
            caseDict = { 'test' : self.test }
            #Call the Method
            try:
                query = caseDict[sys.argv[1]]()
                print "[query]" +query + "[/query]"
            except:
                print "error no such query exists"

    def getArgs(self, needAmount):
        """
        args which wont give will set to None
        """
        
        #called by command line with args
        if not self.callByPython:
            for i in range(len(sys.argv)):
                if i >1:
                    self.ArgList.append(sys.argv[i])

        #SEt the missing args with empty string
        while len(self.ArgList)<needAmount:
            self.ArgList.append("")



#-----------------------just queries down to this-----------------------
  
    def test(self):
        """    
        Arg sequence: rows; table;
        """
        
        #get the Args, argument is the maximum amount of used args
        self.getArgs(2)
        
        query = "select "+ self.ArgList[0] + " from " + self.ArgList[1]
        
        return query




#called if there are arguments entered by command line
if len(sys.argv)>1:
    QueryPool = QueryPool()








#-----------------------end of query class-----------------------

"""
sample how to call it from pyhton


QueryPool = QueryPool(True)

# Set the args in the right sequence, missing args would filled with an empty string
QueryPool.ArgList = ["arg01", "arg02"]

query = QueryPool.test()

print query

"""



"""
sample how to call it from command line
 
command:   test2.py query arg1 arg2
output:    [query]select arg1 from arg2 ...[/query]

You have only to split the string to get the query
"""



Verfasst: Montag 31. Oktober 2005, 15:31
von mbierenfeld
Sockets ? WebServices ? RPC-Server.

*hm* da geht schon was ...

Verfasst: Dienstag 1. November 2005, 01:04
von BlackJack
Also ich find's ziemlich unübersichtlich. Wieso muss die Klasse wissen von wo sie benutzt wird? Warum werden die Argumente nicht im Konstruktor übergeben. Wenn sie von Python aufgerufen wird, dann halt direkt, ansonsten wird ausserhalb der Klasse die Kommandozeile ausgewertet und an den Konstruktor übergeben.

Ob ein Modul als Modul importiert wurde oder als "Hauptprogramm" von der Kommandozeile gestartet wurde stellt man normalerweise fest in dem man sich die anschaut was `__name__` enthält. Mal so als Grundgerüst:

Code: Alles auswählen

import sys

class QueryPool:
    def __init__(self, arguments=None):
        if arguments is None:
            arguments = list()
        self.arguments = arguments
        # Evt. irgend etwas mit den Argumenten anstellen.
    
    # ...


def main():
    if len(sys.argv) > 1:
        pool = QueryPool(sys.argv[1:])
        pool.test()
        # ...

if __name__ == '__main__':
    main()
Wobei ich bei Deinem Quelltext noch nicht so ganz sicher bin ob der das tut, was Du möchtest. `ArgList` und `CallByPython` sind Klassenattribute und keine Instanzattribute. Ist das gewollt?

Verfasst: Mittwoch 2. November 2005, 09:15
von mr.hide
Hallo,

irgend wie bin ich da am Schlauch gestanden.
Hier mal mein gekürzter Code :oops:

Gibt es eigentlich ein Modul womit man von Perl aus direkt Pythonmethoden aufrufen kann?

Grüße
Matthias

Code: Alles auswählen

import sys    

class QueryPool:
   
    def qu1(self, argList):
        """
        argList = [arg1, arg2]
        """
        try:

            query =  "SELECT " + str(argList[0]) + " from " + str(argList[1]) 

        except:
            print "error with args, check if all needed are given" 
            return ""
        return query





#if called by commandline
if __name__ == '__main__':
    QueryPool = QueryPool()
    
    #The available queries
    caseDict = { 'qu1' : QueryPool.qu1 }
   
    try:
        #call the queries with the commandline args
        query = caseDict[sys.argv[1]](sys.argv[2:])
		if query != "":
			print "[query]" + query + "[/query]"
    except:
        print "error no such query exists"

Verfasst: Mittwoch 2. November 2005, 21:48
von BlackJack
Ich weiss er ist gekürzt, aber warum ist QueryPool eine Klasse? `self` wird doch in der Methode gar nicht benutzt. So wie's da steht kan `qu1` auch einfach eine Funktion sein.

Verfasst: Donnerstag 3. November 2005, 08:44
von Gast
damit man in einem großen Projekt den Überblick behält was man einbindet.

Ich komm halt von java, und da packt man einfach alles in Klassen.

Wahrscheinlich Gewohnheit.

Verfasst: Donnerstag 3. November 2005, 08:45
von mr.hide
=> war ich :?

Verfasst: Donnerstag 3. November 2005, 09:39
von gerold
mr.hide hat geschrieben:Gibt es eigentlich ein Modul womit man von Perl aus direkt Pythonmethoden aufrufen kann?
Hi Matthias!

Nicht das ich wüsste. Aber über die Kommandozeile ist ja auch nicht so schlecht, oder?

Ich halte das generell so. Wenn ich keine Geschwindigkeitsrecorde brechen muss, dann rufe ich von einem anderen Programm, das Python-Programm über die Kommandozeile auf. Muss ich verschiedenste Daten übergeben, dann verwende ich "optparse" um diese geregelt übergeben zu können. Müssen viele Daten übergeben werden, dann einige ich mich meistens darauf, die Daten in eine YAML-Datei zu schreiben und den Pfad zu dieser YAML-Datei wiederum über die Kommandozeile zu übergeben. Das Python-Programm arbeitet mit der YAML-Datei und schreibt, falls notwendig, die Daten in eine neue YAML-Datei. Der Pfad zur Ergebnisdatei sollte dann natürlich auch über die Kommandozeile übergeben werden können. Es muss ja keine YAML-Datei sein. Es kann jede Art von Datei sein, die von beiden Programmen interpretiert werden kann.

Ich mache das deshalb, da mein Hauptpgrogramm, eine Warenwirtschaft, noch in Visual Basic geschrieben ist und so etwas nicht einfach im Handumdrehen nach Python übersetzen kann. Meine Python-Programme rufe ich einfach von VB aus über die Kommandozeile auf und das funktioniert ziemlich gut. So bleibe ich ziemlich unabhängig.

Mir gefällt auch, dass ich so die Ausgabe eines Programmes über die Kommandozeile (mit Pipe |) als Input wieder in ein anderes Programm schicken kann, usw...

mfg
Gerold
:-)

Verfasst: Donnerstag 3. November 2005, 09:44
von gerold
gerold hat geschrieben:Aber über die Kommandozeile ist ja auch nicht so schlecht, oder?
In diesem Programm ist die Verwendung von "optparse", meiner Meinung nach, ziemlich gut rüber gekommen. :-)

http://www.python-forum.de/viewtopic.php?t=1811

mfg
Gerold
:-)

Verfasst: Donnerstag 3. November 2005, 14:16
von mbierenfeld
Also ich finde getops eigentlich nicht so schlecht. Bsp s. unten

Code: Alles auswählen


    global logger

    try:

        opts, args = getopt.getopt(argv, "ht:b:d:", 
            ["help", "timeout=", "basedir=", "dirdate="])

    except getopt.error, msg:
        if logger:
            logger.error(msg)
        sys.exit(2)

    for opt, arg in opts:

        if opt in ("-h", "--help"):

            usage (USAGE)
            
        elif opt in ("-t", "--timeout"):
        
            timeout = int (arg)

        elif opt in ("-d", "--dirdate"):
        
            dirdate = arg
        
        elif opt in ("-b", "--basedir"):
        
            basedir = arg


    if not args:
        if logger:        
            logger.error ("no files to wait for given goodbye")
            ret_value = -1
            return ret_value
    files = args    
    err, found = waitfor (files, timeout, basedir, dirdate)