wie ästhetisch ist mein code?

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
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

was haltet ihr von diesem code?
wäre für jede meinung sehr dankbar, hoffe, erstmal alles berücksichtigt zu haben

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite
class Connection:
    def __init__(self):
        self.conn = []
        self.cur = []
        self.conn[0] = sqlite.connect("root.db")
        self.cur[0] = conn[0].cursor()
        self.root_cur = self.cur[0]
    def connect(self):
        self.i = 1 #<-to prevent that root (0) is touched
        self.dblist = []
        self.root_cur.execute("SELECT name FROM INFO")
        for name in self.root_cur.fetchall():
            self.conn[i] = sqlite.connect(name)
            self.cur[i] = self.conn[i].cursor()
            self.dblist[i] = name
            self.i+=1
    def kill(self):
        self.root_cur.execute("SELECT name FROM INFO")
        self.killlist = self.root_cur.fetchall()
        for i in xrange(len(self.killlist)):
            self.cur[i].close()
            self.conn[i].close()
        self.cur[0].close()
        self.conn[0].close()

class Execute(Connection):
    def execute(self,userid,sql):
        self.cur = Connection.cur[self.userid] 
        self.cur.execute(sql)
        self.fetched = self.cur.fetchall()
        if self.fetched:
            return self.fetched
        else:
            return None  
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ohne jetzt auf die Funktionalität einzugehen... Mir persönlich fehlen da ein paar Leerzeilen vor jeder Methode ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

murph hat geschrieben:was haltet ihr von diesem code?
wäre für jede meinung sehr dankbar, hoffe, erstmal alles berücksichtigt zu haben
Mal sehn...

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite
class Connection:
    def __init__(self):
        self.conn = []
        self.cur = []
        self.conn[0] = sqlite.connect("root.db")
        self.cur[0] = conn[0].cursor()
        self.root_cur = self.cur[0]
Wozu self.root_cur?

Code: Alles auswählen

    def connect(self):
        self.i = 1 #<-to prevent that root (0) is touched
        self.dblist = []
        self.root_cur.execute("SELECT name FROM INFO")
        for name in self.root_cur.fetchall():
            self.conn[i] = sqlite.connect(name)
            self.cur[i] = self.conn[i].cursor()
            self.dblist[i] = name
            self.i+=1
Das funktioniert nicht, da du einmal self.i und einmal i verwendest.
Außerdem, schau dir mal enumerate() an.

Ich würde außerdem die name<->connection-Zuordnung über ein dictionary machen und die Cursors bei Bedarf erzeugen.

Code: Alles auswählen

    def kill(self):
        self.root_cur.execute("SELECT name FROM INFO")
        self.killlist = self.root_cur.fetchall()
        for i in xrange(len(self.killlist)):
            self.cur[i].close()
            self.conn[i].close()
        self.cur[0].close()
        self.conn[0].close()
Warum iterierst du nicht einfach über range(len(self.cur))?

Code: Alles auswählen

class Execute(Connection):
    def execute(self,userid,sql):
        self.cur = Connection.cur[self.userid] 
        self.cur.execute(sql)
        self.fetched = self.cur.fetchall()
        if self.fetched:
            return self.fetched
        else:
            return None  
Warum hier eine Subklasse? Außerdem kannst du nicht "cur" auf "Connection" ansprechen (da kein Klassenattribut), sondern nur auf self.

Alles in allem würde ich sagen, teste den Code erstmal vor du ästhetische Ansprüche daran stellst ;-).
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

murph hat geschrieben:wäre für jede meinung sehr dankbar
Hi murph!

Sieht nicht schlecht aus. Ich hätte nur ein paar Kleinigkeiten und eine Sache, die du komplett vergessen hast. --> die Docstrings.

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite
Damit der Code auch später unter Python 2.5 läuft, ohne pySQLite extra installieren zu müssen, schlage ich vor, den Import so zu gestalten:

Code: Alles auswählen

try:
    import sqlite3 # Ab Python 2.5
except:
    from pysqlite2 import dbapi2 as sqlite3

Code: Alles auswählen

self.conn[0] = sqlite.connect("root.db")
Vielleicht lagerst du den Namen "root.db" in eine Konstante oder gar in eine eigene Datei, z.B. eine INI-Datei, aus.
Ich persönlich, erstelle statt einer richtigen Konstante, so etwas gibt es in Python nicht, einfach eine großgeschriebene Variable unterhalb der Imports. Das ist für mich das Zeichen, dass es sich um eine Variable handelt, die im Code nicht verändert werden soll.

Code: Alles auswählen

#: Gibt den Namen zur Einstellungsdatenbank an.
ROOT_DB_NAME = "root.db"
...
...
self.conn[0] = sqlite.connect("ROOT_DB_NAME")
Hinweis: Kommentare, die mit (#:) beginnen, werden seit neuestem in EpyDoc http://epydoc.sourceforge.net/ als Kommentare angezeigt. So kann man endlich wichtige Variablen oder Properties auch so kommentieren, dass diese in EpyDoc berücksichtigt werden.

Code: Alles auswählen

    def connect(self):
        self.i = 1 #<-to prevent that root (0) is touched
        self.dblist = []
        self.root_cur.execute("SELECT name FROM INFO")
        for name in self.root_cur.fetchall():
            self.conn[i] = sqlite.connect(name)
            ...
            ...
In diesem Codeabschnitt verstehe ich noch nicht woher du die Variable "i" nimmst. Zuerst verwendest du "self.i" und dann nur noch "i".

Code: Alles auswählen

self.root_cur.execute("SELECT name FROM INFO")
Ich hatte schon ein paar Probleme mit großgeschriebenen Tabellennamen. Auch wenn das nicht sein muss, aber klein geschriebene Feld- und Tabellennamen machen es einem ab und zu leichter. Ganz besonders auch im Zusammenspiel mit Zope und beim Umsteigen auf andere Datenbanksysteme, da einige die Groß-Kleinschreibung ignorieren und andere nicht.

Code: Alles auswählen

        self.root_cur.execute("SELECT name FROM INFO")
        self.killlist = self.root_cur.fetchall()
        for i in xrange(len(self.killlist)):
            self.cur[i].close()
            self.conn[i].close()
        self.cur[0].close()
        self.conn[0].close()
Den verstehe ich nicht ganz. Du lässt dir alle Namen aus der Tabelle INFO zurück geben, verwendest sie aber nicht.

Code: Alles auswählen

SELECT count(name) FROM INFO
gibt dir die Anzahl der Namen zurück. Damit kannst du dann direkt arbeiten.

EDIT:

Code: Alles auswählen

class Execute(Connection):
    def execute(self,userid,sql):
        self.cur = Connection.cur[self.userid] 
        self.cur.execute(sql)
        self.fetched = self.cur.fetchall()
        if self.fetched:
            return self.fetched
        else:
            return None
Hier erbst du von der Klasse Connection, initialisierst sie aber nicht und ... den rest verstehe ich noch nicht.
Das nehme ich zurück. Ich habe übersehen, dass du die __init__ ja nicht überschreibst. Damit musst du die geerbte __init__ auch nicht explizit aufrufen.

lg
Gerold
:-)
Zuletzt geändert von gerold am Mittwoch 28. Juni 2006, 07:20, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

Wozu self.root_cur?
um später das arbeiten damit zu vereinfachen (das ganze wird importiert)
Das funktioniert nicht, da du einmal self.i und einmal i verwendest.
Außerdem, schau dir mal enumerate() an.

Ich würde außerdem die name<->connection-Zuordnung über ein dictionary machen und die Cursors bei Bedarf erzeugen.
das habe ich nun grundlegend geändert, weil die datenbank doch noch mehr informationen enthalten muss und deshalb mit einer eigenständigen id gearbeitet wird. aebr wieso denn das ganze über ein dict?
ich fand arrays passend, das argument fehlt mir.
Warum iterierst du nicht einfach über range(len(self.cur))?
blindheit, thx! ;)
Warum hier eine Subklasse? Außerdem kannst du nicht "cur" auf "Connection" ansprechen (da kein Klassenattribut), sondern nur auf self.

Alles in allem würde ich sagen, teste den Code erstmal vor du ästhetische Ansprüche daran stellst
hätte ich auch längst, wenn nicht der ubuntuserver down wäre. ;)
musste mein ganzes system neu installieren, weil ich versucht habe, python 2.5 zu installieren und alle szerschossen hatte, daher kein pysqlite2.
aber wie kann man geschickt auf Connection.cur zugreifen?
irgendwas kann ich auch fabrizieren, aber was sinnvolles soll gelernt sein :-)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

murph hat geschrieben: das habe ich nun grundlegend geändert, weil die datenbank doch noch mehr informationen enthalten muss und deshalb mit einer eigenständigen id gearbeitet wird. aebr wieso denn das ganze über ein dict?
ich fand arrays passend, das argument fehlt mir.
Ich weiß ja nicht, was du mit den Arrays machen willst. Aber im Prinzip gehört doch jede Connection zu einer Tabelle mit einem bestimmten Namen. Also erscheint das logisch:
{ 'foo': <Connection zu foo>, 'bar': <Connection zu bar> }
hätte ich auch längst, wenn nicht der ubuntuserver down wäre. ;)
musste mein ganzes system neu installieren, weil ich versucht habe, python 2.5 zu installieren und alle szerschossen hatte, daher kein pysqlite2.
aber wie kann man geschickt auf Connection.cur zugreifen?
Von wo willst du auf was zugreifen, was instanzierst du? Das ist die Frage. Ein etwas kompletteres Schnipsel wäre also von Vorteil.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

ich kanns mal machen...

Code: Alles auswählen

#!/usr/bin/env python
#main.py
#this is licensed under GPL. more infos in the readme.txt
import new_datapool, sys
from users import Session

###init###
start = new_datapool.Connection()
tmp = start.connect()
tmp = new_datapool.Execute()
exe = tmp.execute

session = Session()
##########

class Administration:
    def add_user(self, new_user, new_pw, root_pw)
        if session.login("root","root"):
            exe("INSERT INTO users (id, name, pw) VALUES (%i, %s, %s)" % (get_new_id(), new_user new_pw))
        else:
            print "You are not root!"
            raise SystemError
    def del_user(self, user, root_pw)
        if session.login("root","root"):
            exe("DELETE FROM users WHERE user = %s" % (user)
    def change_
(ist nicht fertig, muss noch viel gemacht werden! wenn hier funktionen fehlen, denk nichts dabei)

Code: Alles auswählen

#!/usr/bin/env python
#new_datapool.py
#this is licensed under GPL. more infos in the readme.txt
from pysqlite2 import dbapi2 as sqlite
class Connection:
    def __init__(self):
        self.conn = []
        self.cur = []
        self.conn[0] = sqlite.connect("root.db")
        self.cur[0] = conn[0].cursor()
        self.root_cur = self.cur[0]
    def connect(self):
        self.i = 1 #<-to prevent that root (0) is touched
        self.dblist = []
        self.root_cur.execute("SELECT id FROM users")
        for id in self.root_cur.fetchall():
            self.conn[id] = sqlite.connect(id+".db")
            self.cur[id] = self.conn[id].cursor()
            self.dblist[id] = name
    def kill(self):
        self.root_cur.execute("SELECT name FROM users")
        self.killlist = self.root_cur.fetchall()
        for i in xrange(len(self.killlist)):
            self.cur[i].close()
            self.conn[i].close()
        self.cur[0].close()
        self.conn[0].close()
    def logout(self, userid):
        self.cur[userid].close()
        self.conn[userid].close()

class Execute(Connection):
    def execute(self,userid,sql):
        self.cur = Connection.cur[self.userid] 
        self.cur.execute(sql)
        self.fetched = self.cur.fetchall()
        if self.fetched:
            return self.fetched
        else:
            return None   

Code: Alles auswählen

#!/usr/bin/env python
#users.py
#this is licensed under GPL. more infos in the readme.txt

import new_datapool

###init###
start = new_datapool.Connection()
tmp = start.connect()
tmp = new_datapool.Execute()
exe = tmp.execute
##########

class Usersettings:
    def __init__(self):
        self.pw_dic = {}
        self.id_dic = {}
        self.query = exe(0,"SELECT id, name, pw FROM users")
        for id, name, pw in self.query:
            self.pw_dic[name] = pw
            self.id_dic[name] = id 
    def get_userid(self, name):
        return self.id_dic[name]
    def get_userpw(self, name):
        return self.pw_dic[name]

class Session:
    def login(self, user, pw):
        self.tmp = Usersettings()
        self.uid = tmp.get_userid(user)
        self.pw_real = tmp.get_userpw(user)
        if self.pw_real == pw:
            return True
        else:
            return False
    def logout(self, user):
        start.logout(get_userid(user))
//edit:
ich mag mein instanzieren nicht, aber hab keine andere lösung gefunden...
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Code: Alles auswählen

start = new_datapool.Connection()
tmp = start.connect()
Ich fände folgendes hübscher:

Code: Alles auswählen

# erstellt eine Connection, bindet sie an den namen conn
conn = new_datapool.Connection() 

# die Methode gibt nichts (strenggenommen None) zurück, wir müssen
# es also nicht speichern
conn.connect()
mal davon ab, dass du scheinbar noch etwas probleme mit Objektorientierung hast.
In der Klasse Execute steht folgendes:

Code: Alles auswählen

self.cur = Connection.cur[self.userid]
Du holst dir also aus der _Klasse_ (und nicht etwa dem objekt, was du instanziierst) den Wert der Klassenvariablen "cur". Die gibt es aber nicht, du behandelst "cur" als Instanzvariable (du setzt sie im Konstruktor von Connection).
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also ich finde den Kommentar doch ein wenig zuviel des guten. Man sollte nichts kommentieren was man eh schon aus dem Code direkt ablesen kann.

Meine Variante:

Code: Alles auswählen

# erstellt eine Connection
conn = new_datapool.Connection()
conn.connect()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Die Kommentare in meinem Code dienten eher der Erklärung, warum so, und nicht wie vorgegeben. Ich wollte einerseits nicht tausend Code-sektionen haben, andererseits aber legalen Code in der Code-sektion.

Würde sowas irgendwo in einem echten Programm stehen, würde ich persönlich auch gerne zur Gewalt greifen.
BlackJack

murph hat geschrieben:

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite
class Connection:
    def __init__(self):
        self.conn = []
        self.cur = []
        self.conn[0] = sqlite.connect("root.db")
        self.cur[0] = conn[0].cursor()
        self.root_cur = self.cur[0]
Das dürfte nicht funktionieren. Du kannst an den Index 0 von den beiden Listen nichts zuweisen, weil es den noch nicht gibt.

Code: Alles auswählen

    def connect(self):
        self.i = 1 #<-to prevent that root (0) is touched
        self.dblist = []
        self.root_cur.execute("SELECT name FROM INFO")
        for name in self.root_cur.fetchall():
            self.conn[i] = sqlite.connect(name)
            self.cur[i] = self.conn[i].cursor()
            self.dblist[i] = name
            self.i+=1
Auch dieser Code wird genau deswegen auf die Nase fallen. Wenn die "Root-Connection" so etwas besonderes ist, dann speicher sie doch einfach nicht in den Listen. Dann brauchst Du sie auch nicht umgehen.

Code: Alles auswählen

    def kill(self):
        self.root_cur.execute("SELECT name FROM INFO")
        self.killlist = self.root_cur.fetchall()
        for i in xrange(len(self.killlist)):
            self.cur[i].close()
            self.conn[i].close()
        self.cur[0].close()
        self.conn[0].close()
Warum befragst Du hier überhaupt die Datenbank? Ich würde denken Du möchtest alle offenen Cursor und Connections schliessen, egal wieviele Einträge sich *jetzt* in der Datenbanktabelle befinden. Ausserdem werden die beiden an Index 0 zweimal geschlossen. Und eventuell der letzte Eintrag gar nicht weil Du nur von der Länge der INFO Tabelle ausgehst.

Wenn die Listen `cur` und `conn` am gleichen Index jeweils eine Connection und einen Cursor enthalten, die zusammen gehören, dann könnte man die auch in einer Liste halten und immer ein Tupel mit beiden hineintun.

Code: Alles auswählen

class Execute(Connection):
    def execute(self,userid,sql):
        self.cur = Connection.cur[self.userid] 
        self.cur.execute(sql)
        self.fetched = self.cur.fetchall()
        if self.fetched:
            return self.fetched
        else:
            return None  
Wo kommt `self.userid` her? Warum wird `userid` nicht benutzt? Und warum erbt `Execute` von `Connection`?

Zum Stil: Du machst lokale Namen zu Attributen die es nicht sein müssten. Lokale Namen sollten auch lokal bleiben sonst müllt man sich das Objekt mit Attributen zu. Ausserdem sollte man alle Attribute in der `__init__()` Methode setzen, damit behält man viel besser den Überblick welche Attribute es gibt. Wenn man welche ausserhalb neu einführt, sollte man gute Gründe haben.
BlackJack

murph hat geschrieben:ich kanns mal machen...

Code: Alles auswählen

#!/usr/bin/env python
#main.py
#this is licensed under GPL. more infos in the readme.txt
import new_datapool, sys
from users import Session

###init###
start = new_datapool.Connection()
tmp = start.connect()
tmp = new_datapool.Execute()
exe = tmp.execute
Genau das gleiche machst Du weiter unten nochmal. Wenn man anfängt Quelltext zu duplizieren, sollte man überlegen das in eine Funktion zu stecken die man dann aufruft.

Code: Alles auswählen

session = Session()
##########

class Administration:
    def add_user(self, new_user, new_pw, root_pw)
        if session.login("root","root"):
            exe("INSERT INTO users (id, name, pw) VALUES (%i, %s, %s)" % (get_new_id(), new_user new_pw))
        else:
            print "You are not root!"
            raise SystemError
    def del_user(self, user, root_pw)
        if session.login("root","root"):
            exe("DELETE FROM users WHERE user = %s" % (user)
    def change_
(ist nicht fertig, muss noch viel gemacht werden! wenn hier funktionen fehlen, denk nichts dabei)
Das mit `exe` ist nicht so schön. Ebenfalls nicht gut ist das interpolieren der Argumente in den SQL-Befehl. Das sollte man dem Datenbankmodul überlassen. Überleg zum Beispiel mal was passiert wenn ein user so heisst: 'foo; DROP TABLE users;'

`add_user()` und `del_user()` müssen auch nicht in einer Klasse stecken. Normale Funktionen genügen hier.

Code: Alles auswählen

#!/usr/bin/env python
#new_datapool.py
#this is licensed under GPL. more infos in the readme.txt
from pysqlite2 import dbapi2 as sqlite
class Connection:
    def __init__(self):
        self.conn = []
        self.cur = []
        self.conn[0] = sqlite.connect("root.db")
        self.cur[0] = conn[0].cursor()
        self.root_cur = self.cur[0]
    def connect(self):
        self.i = 1 #<-to prevent that root (0) is touched
        self.dblist = []
        self.root_cur.execute("SELECT id FROM users")
        for id in self.root_cur.fetchall():
            self.conn[id] = sqlite.connect(id+".db")
            self.cur[id] = self.conn[id].cursor()
            self.dblist[id] = name
    def kill(self):
        self.root_cur.execute("SELECT name FROM users")
        self.killlist = self.root_cur.fetchall()
        for i in xrange(len(self.killlist)):
            self.cur[i].close()
            self.conn[i].close()
        self.cur[0].close()
        self.conn[0].close()
    def logout(self, userid):
        self.cur[userid].close()
        self.conn[userid].close()

class Execute(Connection):
    def execute(self,userid,sql):
        self.cur = Connection.cur[self.userid] 
        self.cur.execute(sql)
        self.fetched = self.cur.fetchall()
        if self.fetched:
            return self.fetched
        else:
            return None   
Hier stellt sich die Frage warum `Execute` von `Connection` erbt und `Connection` nicht einfach eine `execute()` Methode hat. So funktioniert das auch gar nicht.

Und neben `sql` sollte es noch einen extra Parameter für eventuelle Argumente geben die dann als zweites Argument an die `execute()` Methode des Cursors übergeben werden um SQL-Injection Angriffe zu verhindern.

Code: Alles auswählen

#!/usr/bin/env python
#users.py
#this is licensed under GPL. more infos in the readme.txt

import new_datapool

###init###
start = new_datapool.Connection()
tmp = start.connect()
tmp = new_datapool.Execute()
exe = tmp.execute
##########

class Usersettings:
    def __init__(self):
        self.pw_dic = {}
        self.id_dic = {}
        self.query = exe(0,"SELECT id, name, pw FROM users")
        for id, name, pw in self.query:
            self.pw_dic[name] = pw
            self.id_dic[name] = id 
    def get_userid(self, name):
        return self.id_dic[name]
    def get_userpw(self, name):
        return self.pw_dic[name]

class Session:
    def login(self, user, pw):
        self.tmp = Usersettings()
        self.uid = tmp.get_userid(user)
        self.pw_real = tmp.get_userpw(user)
        if self.pw_real == pw:
            return True
        else:
            return False
    def logout(self, user):
        start.logout(get_userid(user))
Auch das funktioniert so nicht. Hast Du eigentlich irgendwas davon mal ausprobiert?

Jedesmal beim `login()` werden alle Benutzer aus der Tabelle ausgelesen. Da könnte man schonmal die Klasse `Usersettings` weglassen und in `Session.login()` nur die Daten für den Benutzer holen der sich gerade anmelden möchte.

In einer ``if``/``else`` Konstruktion `True` zurückzugeben wenn ein Vergleich wahr ergibt und `False` sonst ist übrigens eine langatmige Umschreibung für:

Code: Alles auswählen

return real_pw == pw
//edit:
ich mag mein instanzieren nicht, aber hab keine andere lösung gefunden...
Wie wär's wenn Du keine Klassen benutzt wo es nicht nötig ist!? Dann sparst Du die auch das Erstellen von den Objekten.

Eine schöne Eigenschaft von Python ist, das man sehr schön ein Programm Funktion um Funktion schreiben kann und schnell ausprobieren kann, ob's immer noch, oder schon so, funktioniert wie man sich das denkt. Du schreibst hier einen Haufen Module und Klassen ohne es auch nur einmal ausprobiert zu haben.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

danke für die zahlreiche kritik!
ich werde auf jeden fall folgende veränderungen vornehmen:
in die klasse Connection wird execute mit hineingezogen.
der login wird überarbeitet (die if/else-geschichte)
tabelle heißt users
python 2.5-gerecht umschreiben (abwärtskompatibel)
self.userid wird zu userid
:oops: die liste wird gerichtet, sodass sie funktionieren kann :oops:
aber
@blackjack:
ich werde sonst einfach so einen usernamen verbieten...
oder gibt es eine einfache sache, wie man das doch noch hinbekommt, das variablensetzen? habs bisher noch nirgends gelesen
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:oder gibt es eine einfache sache, wie man das doch noch hinbekommt, das variablensetzen? habs bisher noch nirgends gelesen
Staht doch schon da:
BlackJack hat geschrieben:Und neben `sql` sollte es noch einen extra Parameter für eventuelle Argumente geben die dann als zweites Argument an die `execute()` Methode des Cursors übergeben werden um SQL-Injection Angriffe zu verhindern.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

aber das lößt nicht das problem, wenn einer "; DROP users" heißt...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:aber das lößt nicht das problem, wenn einer "; DROP users" heißt...
Nein, welches Problem sollte es dann lösen? "; DROM users" ist eine typische SQL_Incejtion und eben dafür hat BlackJack das Lösungsverfahren aufgezeigt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

soweit, wie ich das verstanden habe, ist das, um weitere befehle anzunehmen.

Code: Alles auswählen

>>> def a(*args):
...     print args
...
>>>
>>> a()
()
>>> a("hallo")
('hallo',)
>>> a("hallo","du")
('hallo', 'du')
aber wieso soll das vor dem usernamen ";DROP users" schützen?
da habe ich leider noch zu wenig erfahrung, um da einen zusammenhang zu sehen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:aber wieso soll das vor dem usernamen ";DROP users" schützen?
Stimmt, das was du gemacht hast, schützt keinen deut. Aber lies doch mal genauer was BlackJack geschrieben hat:
BlackJack hat geschrieben:Und neben `sql` sollte es noch einen extra Parameter für eventuelle Argumente geben die dann als zweites Argument an die `execute()` Methode des Cursors übergeben werden um SQL-Injection Angriffe zu verhindern.
Und jetzt noch ein Link dazu.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

ich habs gefunden:
That's all there is to it. Pass y as a parameter, and all your cracker will do is set the value of name to their string, as pysqlite will trawl through and make sure there are no double quotes within the string to be inserted.
vorhaer wusste ich gar nichts von dieser zusatzfunktion von pysqlite2.
naja, wenn man ein modul nicht gut genug kennt.......
x,X
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

murph hat geschrieben:vorhaer wusste ich gar nichts von dieser zusatzfunktion von pysqlite2.
Das ist keine Zusatzfunktion von PySQLite sondern Teil des PEP 249: DB-API 2.0 und wird daher von allen DB-API 2.0 kompatiblen Bindings bereitgestellt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten