Seite 1 von 1
allgemeine fragen zu klassen
Verfasst: Donnerstag 26. November 2009, 09:44
von naked_chef
hi,
ich befasse mich gerade etwas mit klassen und habe da anscheinend ein kleines versändnissproblem:
ich möchte auf einem entfernten host, per ssh zugreiffen, befehle ausführenlassen und den output auswerten bzw. anzeigen lassen.
mit paramiko hab ich dafür auch schon das passende werkzeug gefunden.
in einer funktion verpackt klappt auch das importieren und nutzen des modules.
jetzt möchte ich nicht jedesmal die verbindung neu initialisieren müssen wenn ich mehrere abfragen hintereinander mache. da die reihnfolge variiert ist es auch nicht da ziel alle möglichen variationen in unterschiedliche funktionen zu packen.
also eine klasse. (ich hoffe, dass das der richtige weg ist)
Code: Alles auswählen
import paramiko
class Ssh(object):
def __init__(self, host, sysuser):
paramiko.util.log_to_file('paramiko.log')
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=host, username=sysuser, key_filename='~/.ssh/id_rsa')
def get_current_auth(self):
stdin, stdout, stderr = client.exec_command('cat ~/.ssh/authorized_keys')
type(stdin)
res = stdout.readlines()
return res
def __del__(self):
client.close()
ich kann die klasse/verbindung initialisieren.
wenn ich die methode "get_current_auth" ausführen möchte, bekomme ich die meldung, dass "client" nicht definiert ist.
das sind meine ersten gehversuche mit klassen, daher hab ich bestimmt irgendwo einen gravierenden denkfehler.
kann ich meine vorstellung überhaupt mit einer klasse umsetzen ?
gruss naked
Verfasst: Donnerstag 26. November 2009, 09:49
von EyDu
Hallo.
Es sollte statt "client" immer "self.client" heißen. Ohne das "self" ist der Name lokal, mit self gehört er zum Objekt.
"__del__" solltest du übrigens nicht verwenden, es ist nicht garantiert, dass es jemals aufgerufen wird. Füge besser eine Methode hinzu, mit der du explizit die Verbindung beenden kanst.
Verfasst: Donnerstag 26. November 2009, 09:49
von cofi
`__del__` sollte man nicht nutzen, zum Einen ist nicht garantiert, wann oder ob sie beim aufräumen aufgerufen wird und zum anderen kann man sich damit wunderbar zirkuläre Abhängigkeiten aufbaun.
`client` ist in `__init__` ein lokaler Name, darum kannst du ihn in `get_current_auth` nicht aufrufen. Stelle deinen Namen, die an das Exemplar gebunden werden sollen ein `self.` vor und es klappt.
Das kannst du mit Klassen umsetzen, die Frage ist allerdings, ob die überhaupt eine benötigst.
Verfasst: Donnerstag 26. November 2009, 10:05
von naked_chef
cofi hat geschrieben:
Das kannst du mit Klassen umsetzen, die Frage ist allerdings, ob die überhaupt eine benötigst.
wieso ?
ich habe meine klassen entsprechend angepasst und jetzt klappt es.
Code: Alles auswählen
import paramiko
class Ssh(object):
def __init__(self, host, sysuser):
paramiko.util.log_to_file('paramiko.log')
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(hostname=host, username=sysuser, key_filename='/var/www/.ssh/id_rsa')
def get_current_auth(self):
stdin, stdout, stderr = self.client.exec_command('cat ~/.ssh/authorized_keys')
type(stdin)
res = stdout.readlines()
return res
def close(self):
self.client.close()
def __del__(self):
pass
nur nochmal zum verständniss.
wenn ich eine methode mit "self." ausführe ist sie klassen weit verfügbar.
ohne nur in der aktuellen methode ?
danke.
Verfasst: Donnerstag 26. November 2009, 10:21
von DasIch
Du solltest auf eine __del__ Methode besser verzichten. Die kann erstaunlich oft dazu führen dass der GC nicht mehr alles aufräumt.
Verfasst: Donnerstag 26. November 2009, 10:22
von /me
naked_chef hat geschrieben:nur nochmal zum verständniss.
wenn ich eine methode mit "self." ausführe ist sie klassen weit verfügbar.
ohne nur in der aktuellen methode ?
Wenn du eine Methode mit self aufrufst dann muss diese Methode in der Instanz der Klasse definiert sein.
Wenn du in einer Methode eine Zuweisung zu self.
variablenname durchführst dann kannst du in allen Methoden dieser Instanz mit self.
variablenname darauf zugreifen.
Verfasst: Donnerstag 26. November 2009, 10:29
von naked_chef
okay - alles verstanden.
und die __del__-methode ist gelöscht.
in vielen erklärungen stand halt das man __del__ einfach als leere funktion angeben soll und wenn man das erstemal mit klassen zutun hat, glaubt man natürlich alles.
danke für die hilfe und die hinweise
Verfasst: Donnerstag 26. November 2009, 12:17
von ms4py
naked_chef hat geschrieben:in vielen erklärungen stand halt das man __del__ einfach als leere funktion angeben soll und wenn man das erstemal mit klassen zutun hat, glaubt man natürlich alles.
War das vielleicht zufälligerweise das OpenBook von Galileo? Wenn ja, weg damit, das ist Schrott... Zur Einführung in Python ist "A Byte of Python" sehr gut.
Verfasst: Donnerstag 26. November 2009, 12:24
von lunar
ice2k3 hat geschrieben:Wenn ja, weg damit, das ist Schrott...
Und es gibt sogar eine
Begründung dafür

Verfasst: Donnerstag 26. November 2009, 12:33
von ms4py
lunar hat geschrieben:ice2k3 hat geschrieben:Wenn ja, weg damit, das ist Schrott...
Und es gibt sogar eine
Begründung dafür

Wobei die "average"-Funktion des Authors auch nicht viel besser ist. Zuwas gibt es "sum" und "len"...
Edit: Das ist ja von BlackJack...
Warum nicht so:
Code: Alles auswählen
def average(iterable, start=0):
return sum(iterable, start) / len(iterable)
Edit2:
Für eine "echte" Durchschnittsfunktion wäre eine explizite Float-Konvertierung oder ein
auch noch notwendig.
Verfasst: Donnerstag 26. November 2009, 12:53
von lunar
@ice2k3: Überlege mal, welche Typen Deine Funktion und welche Typen BlackJacks Funktion verarbeiten kann. BlackJacks Funktion
ist besser
Im Bezug auf die Fleißkommadivision dagegen hast Du meines Erachtens Recht.
Verfasst: Donnerstag 26. November 2009, 13:08
von naked_chef
der part mit der objektorientierung ist tatsächlich aus diesem buch - schande über mein haupt
ich muss aber zugeben, dass das ich das openbook schnell wieder geschlossen habe als mir auffiel das es viele ungereimtheiten in den verwendeten beispielen gab.
ausser für das thema OOP hab ich es nochmal rausgeholt - und anscheinend war auch das falsch.
Verfasst: Donnerstag 26. November 2009, 13:17
von cofi
naked_chef hat geschrieben:ausser für das thema OOP hab ich es nochmal rausgeholt - und anscheinend war auch das falsch.
Dort ist es im Besonderen schlimm, da die Autoren Java in Python-Syntax schreiben und es sich hier am stärksten niederschlägt.
Ob du eine Klasse benötigst hängt davon ab, was du machen willst, das lässt sich daraus noch nicht ablesen - auch wenn der Code es IMHO atm noch nicht rechtfertigt.
Verfasst: Donnerstag 26. November 2009, 13:31
von naked_chef
okay dann muss ich leider etwas weiter ausholen, allerdings ist das dann dafür wahrscheinlich das falsche unterforum.
ich habe den auftrag ein verwaltungstool für ssh zugänge zu erstellen.
da ich mit python auf der commandline gut erfahrungen gemacht habe war die sprache meiner wahl python.
nachdem ich (auch dank dem forum hier) es geschafft habe die vorgabe von mod_python zu kippen und stattdessen auf django umgestiegen bin, kamen halt klassen ins spiel, vor diese habe ich mich bisher erfolgreich gedrückt.
dank django muss ich mich im solche sachen wie DB anbindung zum glück nicht weiter kümmern. allerdings würde ich halt ein einhaltliches interface haben wollen und müsste daher ein ssh-modul so verfassen dass ich es möglichst auch über das django-admin-interface verwaltbar ist. -klassen-
in einer DB sind user (username, voller name, mail, und public key), sowie host (hostname, location) hinterlegt. um keine inkonsistenzen zu erzeugen hole ich die aktuellen systemuser von den hosts per ssh.
anhand eines interfaces soll dann der user aus der datenbank einen systemuser auf einem host aus der datenbank zugeordnet, eine neue authorized_keys erzeugt und auf den host an den entsprechenden systemuser weiter gegeben werden.
und als sysadmin - und neuling im bereich der OOP gibt es halt viele fragen die ich gerade stück für stück beantworte. ab jetzt aber nicht mehr mit dem openbook.
zum glück ist django gut dokumentiert und es geht langsam vorran.