Verknüpfungsprobleme

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
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

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*
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

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.
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.
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

hallo,

könnte ich nicht set_power als klasse in a.py definieren und read() von b.py in die klasse integrieren ?
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.
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

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.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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()
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

hallo

kann ich read aufrufen, ohne die klasse zu initialisieren?
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

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)
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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?
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

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
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

gpib wird doch nur beim Erzeugen der Klasse gesetzt... Read ändert das nicht.
N317V
User
Beiträge: 504
Registriert: Freitag 8. April 2005, 13:23
Wohnort: München

Ach dafür ist das @staticmethod gut!
Es gibt für alles eine rationale Erklärung.
Außerdem gibt es eine irrationale.

Wie man Fragen richtig stellt
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

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?
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

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.
riven
User
Beiträge: 35
Registriert: Mittwoch 27. September 2006, 23:01

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
Antworten