Seite 1 von 1

Verknüpfungsprobleme

Verfasst: Freitag 27. Oktober 2006, 13:50
von riven
hallo,

mit dem programm a.py importiere ich alle subroutinen von b.py.
in b.py habe ich u.a. diese subroutinen:

Code: Alles auswählen

def gpib_access(addr):
    global gpib
    gpib=[ gpibAccessUsb(addr,0)]

def read():
    s=""
    arr=cArray(100)
    arr[0]='\0'
    i=0
    for g in gpib:
        while(i<100 and ord(arr[0])!=10):
            g.read(arr,1)
            usw.
in a.py habe ich folgendes unterprogramm:

Code: Alles auswählen

def set_power():#with Agilent E3640A
    
    gpib_access(7)#Supply Voltage
    for g in gpib:
        sendGPIB(g,"*rst")
        usw.
    supply=read()[0]

in a.py habe ich zudem:

Code: Alles auswählen

if __name__=="__main__":
    set_power()
wenn ich a.py starte, bekomme ich die fehlermeldung:

Code: Alles auswählen

for g in gpib:
NameError: global name 'gpib' is not defined
wenn ich aber in a.py folgendes habe:

Code: Alles auswählen

if __name__=="__main__":
    gpib=[ gpibAccessUsb(8,0)]
    set_power()
dann klappt es.wie kann ich dieses problem lösen, dass nur in diesem fall gpib erkannt wird? ich würde nämlich viel lieber mit parametern arbeiten als "zu fuß".

Edit (Leonidas): Code wieder einmal in Python-Tags gesetzt *sigh*

Verfasst: Freitag 27. Oktober 2006, 14:12
von N317V

Verfasst: Freitag 27. Oktober 2006, 14:49
von riven
hi, ich stelle die frage mal anders:

wie kann ich dafür sorgen, dass gpib nicht verloren geht ?
kann ich in b.py eine klasse einbauen mit einem parameter ? dabei soll diese klasse das unterprogramm read() beinhalten.

Verfasst: Freitag 27. Oktober 2006, 14:58
von BlackJack
``global`` heist "Modul-Global", das heisst `gpib_access()` bindet `gpib` im Modul `b` an die Liste. ``global`` sollte man aber möglichst nicht benutzen. Warum kann `gpib_access` nicht einfach die Liste als Rückgabewert liefern?

Und im Modul `a` sollte `set_power()` das Objekt `gpib` als Argument übergeben bekommen und nicht einfach im Modul danach suchen.

<mantra>Werte betreten Funktionen als Argumente und verlassen Funktionen als Rückgabewerte.</mantra>

Siehst ja selbst wie schnell es verwirrend und unübersichtlich wird wenn man diese vorgesehenen Schnittstellen umgeht.

Verfasst: Freitag 27. Oktober 2006, 15:10
von riven
hallo,

könnte ich nicht set_power als klasse in a.py definieren und read() von b.py in die klasse integrieren ?

Verfasst: Freitag 27. Oktober 2006, 16:23
von BlackJack
`set_power()` ist eine Funktion. Man macht aus Funktionen nicht einfach so Klassen. Wo soll denn dann der Code aus der Funktion selbst hin? Und wieviele `SetPower` Objekte brauchst Du in Deinem Programm dann?

Ich wiederhol's nochmal: Arbeite mit Argumenten und Rückgabewerten und mach nicht einfach Objekte global verfügbar und bastel nicht wild irgendwelche Klassen.

Das klingt alles ziemlich chaotisch was Du da machst.

Verfasst: Donnerstag 2. November 2006, 14:00
von riven
hallo,

das problem dabei ist, dass beim ausführen des befehls gpibaccessUsb ein reset am angeschlossenen gerät gesetzt wird.
ich will also dafür sorgen, dass gpib=gpibaccessUsb einmal ausgeführt wird und existent bleibt, bis der befehl erneut auftaucht.

Verfasst: Freitag 3. November 2006, 21:48
von Joghurt
Wie wär's mit einer Klasse?

Code: Alles auswählen

class GPIB(object):
  def __init__(self, addr):
    self.gpib=[gpibAccessUsb(addr,0)]

  def read(self):
    s=""
    arr=cArray(100)
    arr[0]='\0'
    i=0
    for g in self.gpib:
        while(i<100 and ord(arr[0])!=10):
            g.read(arr,1)
            usw.

mein_gpib = GPIB(42)
mein_gpib.read()

Verfasst: Dienstag 7. November 2006, 18:45
von riven
hallo

kann ich read aufrufen, ohne die klasse zu initialisieren?

Verfasst: Dienstag 7. November 2006, 19:04
von N317V

Code: Alles auswählen

>>> class XXX:
... 	def cheese(self):
... 		print 'This is not pr0n!'
... 		
>>> XXX.cheese
<unbound method XXX.cheese>
>>> XXX.cheese()
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
TypeError: unbound method cheese() must be called with XXX instance as first argument (got nothing instead)

Verfasst: Dienstag 7. November 2006, 20:23
von Joghurt

Code: Alles auswählen

class Foo(object):
    @staticmethod
    def read():
        print "Hallo"

Foo.read()
wobei das deinem ursprünglichen Zweck doch zuwider läuft, oder nicht?

Verfasst: Dienstag 7. November 2006, 22:02
von riven
hi

das problem ist, dass ich für eine unterfunktion die initialisierung brauche. für das unterprogramm read() darf aber nicht initialisiert werden, da sonst gpib resettet wird. wenn ich also eine andere unterfunktion aufrufe, muss gpib unberührt bleiben.
ich werde es morgen mit der @staticmethod - methode ausprobieren.

danke

Verfasst: Dienstag 7. November 2006, 22:15
von Joghurt
gpib wird doch nur beim Erzeugen der Klasse gesetzt... Read ändert das nicht.

Verfasst: Mittwoch 8. November 2006, 10:03
von N317V
Ach dafür ist das @staticmethod gut!

Verfasst: Mittwoch 8. November 2006, 10:57
von riven
klappt diese methode auch, wenn ich aus anderen modulen diese klasse aufrufe? also das setzen von gpib und anschliessend read(), ohne dass gpib verloren geht?

Verfasst: Mittwoch 8. November 2006, 11:32
von Joghurt
Nein, Staticmethod sorgt dafür, dass eine Methode statisch wird, also unabhängig von der jeweiligen Instanz der Klasse (daher auch kein self).

Du willst ja gerade, dass read auf die Instanzvariable self.gpib zugreift, mein erster Code macht also das, was du willst.

Verfasst: Mittwoch 8. November 2006, 11:43
von riven
hi,

ich bin jetzt soweit, dass ich auf read zugreifen kann. mein problem ist, dass der ausgelesene string der hauptfunktion test.py übergeben wird:

Code: Alles auswählen

#test.py
def Sweep():
    commands=[]
    commands.append("*rst")
    commands.append(":OUTPUT ON")
    commands.append(":SYST:BEEP:STAT 0")
    commands.append(":SOURCE:DELAY 0.1")
    commands.append(":SENS:FUNC \"VOLT:DC\"")
    commands.append(":SENS:VOLT:PROT 1.8")
    commands.append(":SOUR:CURR:MODE FIX")
    commands.append(":SOUR:CURR:Range 1")
    commands.append(":SOUR:CURR:LEV 0.1")#+str(i_vdda))
    commands.append(":OUTPUT ON")
    commands.append(":FORM:ELEM CURR")
    Keithley2400.send(commands, read=True)

if __name__=="__main__":
    Sweep()

Code: Alles auswählen

#Kethley2400.py

class Keithley_2400(object): 
    def __init__(self, addr):
        self.gpib=[gpibAccessUsb(addr,0)]

    def read_2400(self):#Keithley 2400
        s=""
        arr=cArray(100)
        arr[0]='\0'
        i=0
        for g in self.gpib:
            while(i<10000 and ord(arr[0])!=10):
                g.read(arr,1)
                s+=arr[0]
                i+=1
        print s
        return s

    def send(self,commands=False, read=False):
        print commands
        for g in self.gpib:
            for i in range(0,len(commands)):
                g.write(commands[i],len(commands[i]))
            if read:
                value=self.read_2400()
                #der wert, der durch den befehl self.read_2400() am interaktiven fenster ausgegeben wird, soll an test.py übergeben werden
   
def send(commands=False, read=False):
    send_commands = Keithley_2400(26).send(commands, read)

danke