was ist in python eigentlich besser ?
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
BlackJacks Einwand bleibt da immernoch bestehen (allerdings zur Intention nicht direkt am Code) und die Funktionen tun nun wirklich nichts aequivalentes.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Wieso nicht ?
Mir geht es ja nicht um eine explizite Typ-Prüfung, sondern nur um den Zugriff auf die Liste, Tuple, Dict und das Objekt.
So das ich an die Daten komme, sicher BlackJack hat schon ganz recht sowas sollte man sehr selten oder gar nicht anbieten.
Mir geht es ja nicht um eine explizite Typ-Prüfung, sondern nur um den Zugriff auf die Liste, Tuple, Dict und das Objekt.
So das ich an die Daten komme, sicher BlackJack hat schon ganz recht sowas sollte man sehr selten oder gar nicht anbieten.
@Xynon1: Kannst Du nicht einfach mehrere Funktionen für die verschiedenen Typen anbieten? Die können sich ja letztendlich alle auf eine stützen, welche die tatsächliche Arbeit verrichtet.
Du machst zwar keine explizite Typ-Prüfung, aber Du probierst verschiedene APIs nacheinander aus -- das sollte man IMHO auch nur in Ausnahmefällen machen, weil's doch sehr magisch und implizit ist.
Kannst Du den Daten-Objekten nicht schon vorher eine gleiche API verpassen, notfalls mit einem Wrapper-Objekt?
Du machst zwar keine explizite Typ-Prüfung, aber Du probierst verschiedene APIs nacheinander aus -- das sollte man IMHO auch nur in Ausnahmefällen machen, weil's doch sehr magisch und implizit ist.
Kannst Du den Daten-Objekten nicht schon vorher eine gleiche API verpassen, notfalls mit einem Wrapper-Objekt?
Mehrere Funktionen für sowas finde ich eigentlich nicht sehr schön, das erinnert dann eher an typsichere Sprachen.
Nein, ist ok ich ändere ich den input voher und die Funktion kann dann halt nur noch Tuple und Listen akzeptiert.
Ich weißBlackJack hat geschrieben:weil's doch sehr magisch und implizit ist.

Nein, ist ok ich ändere ich den input voher und die Funktion kann dann halt nur noch Tuple und Listen akzeptiert.
@Xynon1: Also ich halte Python für typsicher. Typsicher und statisch typisiert sind IMHO zwei verschiedene Dinge. C zum Beispiel würde ich nicht als 100% typsicher ansehen, obwohl es statisch typisiert ist.
Wenn du einen Test machst wird 2 mal versucht den Schlüssel im dict zu finden, wenn du den KeyError abfängst nur einmal.Xynon1 hat geschrieben:@numerix und @DasIch 8.
Ähm bitte mit begründen, sonst hat der Thread wohl keinen sinn
Wenn du *args verwendest kannst du zu einem späteren Zeitpunkt die Signatur nicht mehr verändern, bei **kwargs kannst du keine keyword Argumente mehr hinzufügen. Vorrausgesetzt du willst rückwärtskompatibel bleiben.@DasIch 7.
Detallierter bitte![]()
Ok, leuchtet ein.
Kann man bei "unveränderbaren" *args zB in einem Konstrucktor dann ohne Bedenken eingesetzt werden ?
Denn wenn ich mir mal einige Python-Module aus der Standardlib ansehe, sind nutzen eigentlich nicht allzu wenige diese Möglichkeiten, aber werde sie demnächst nach möglichkeit vermeiden.
Noch ein Beispiel:
Kann man bei "unveränderbaren" *args zB in einem Konstrucktor dann ohne Bedenken eingesetzt werden ?
Denn wenn ich mir mal einige Python-Module aus der Standardlib ansehe, sind nutzen eigentlich nicht allzu wenige diese Möglichkeiten, aber werde sie demnächst nach möglichkeit vermeiden.
Noch ein Beispiel:
Code: Alles auswählen
list_ = [1,2,3,4]
#besser dies
",".join([str(value) for value in list_])
#oder das
",".join(map(str, list_))
Wenn du die "Stern-Variante" vermeiden willst, könntest du das Problem einigermaßen mit einer Hilfsfunktion umgehen:
Hierbei wird alles außer Zeichenketten durch den `list()`-Konstruktor gejagt. Iterierbare Objekte gehen durch die Umwandlung und werden zurückgegeben. Falls die Umwandlung fehlt schlägt (z.B. bei Zahlen) oder wenn es sich um eine Zeichenkette handelt, wird eine einelementrige Liste mit dem `arg` zurückgegeben. Dies führt dazu, dass man später grundsätzlich über den Rückgabewert iterieren kann, also in etwa das hat, was beim Stern rausgekommen wäre. Der Vorteil: Wenn man als Benutzer nur ein Argument mitgeben will, muss man keine Liste erstellen, da dies später implizit von der Funktion gemacht wird.
Code: Alles auswählen
In [1]: def args2list(args):
...: try:
...: if not isinstance(args, basestring):
...: return list(args)
...: except TypeError:
...: pass
...: return [args]
...:
In [2]: args2list(23)
Out[2]: [23]
In [3]: args2list('bla')
Out[3]: ['bla']
In [4]: args2list(['bla', 'blupp'])
Out[4]: ['bla', 'blupp']
In [5]: args2list(xrange(3))
Out[5]: [0, 1, 2]
In [6]: def test(args):
...: for arg in args2list(args):
...: print arg
[...]
Diese Bedenken sind ja eher theoretischer Natur. Es könnte halt als sauberer angesehen werden, weil `*` und `**` bei der Verwendung weiterer Argumente in der Signatur blöde Nebeneffekte haben. Wenn du einfach nur einen Wrapper machst, der die Argumente quasi ungesehen weitergibt, dann finde ich Sterne nicht so tragisch.Xynon1 hat geschrieben:Kann man bei "unveränderbaren" *args zB in einem Konstrucktor dann ohne Bedenken eingesetzt werden ?
Denn wenn ich mir mal einige Python-Module aus der Standardlib ansehe, sind nutzen eigentlich nicht allzu wenige diese Möglichkeiten, aber werde sie demnächst nach möglichkeit vermeiden.
@DasIch: Einen Schlüssel in einem Wörterbuch zu finden, ist nicht aufwendig und geschieht in konstanter Zeit. Demgegenüber ist das Abfangen von Ausnahmen wesentlich teurer als ein Funktionsaufruf. Folglich ist – wie Numerix festgestellt hat – die Variante mit dem Test schneller, sobald Ausnahmen mit einer bestimmten Häufigkeit ausgelöst werden.
Unabhängig davon ist das eine Frage der Intention. Ausnahmen bezeichnen einen „Ausnahmezustand“, und sollten demnach nur zur Behandlung solcher Zustände eingesetzt werden. Möchte man dagegen verschiedene Dinge tun, je nach dem ob der Schlüssel enthalten ist oder nicht, also eine Entscheidung treffen, so ist die Abfrage die natürlichere und idiomatischere Variante.
Das zweifache Nachschlagen des Schlüssels lässt sich mit ".get()" vermeiden.
Unabhängig davon ist das eine Frage der Intention. Ausnahmen bezeichnen einen „Ausnahmezustand“, und sollten demnach nur zur Behandlung solcher Zustände eingesetzt werden. Möchte man dagegen verschiedene Dinge tun, je nach dem ob der Schlüssel enthalten ist oder nicht, also eine Entscheidung treffen, so ist die Abfrage die natürlichere und idiomatischere Variante.
Das zweifache Nachschlagen des Schlüssels lässt sich mit ".get()" vermeiden.
Ja, für neue Themen sollte man auch neue "Themenstränge" machen. Der Themenstrang sollte dabei nicht "Ich bin Anfänger und stelle diverse Fragen zu Python" lauten.Xynon1 hat geschrieben:Mit anderen Worten ich hätte 5 - 10 Threads öffnen sollen deswegen ?
Bedenke immer, dass in 4 Monaten jemand auf den Thread stoßen könnte, weil er ein entsprechendes Suchwort eingegeben hat. Derjenige hat dann wenig Lust, immer Beiträge zu ganz anderen Themen in den Antworten zu haben, nur weil du als Fragesteller zu faul warst, neue Threads aufzumachen. Will man es von der "wissenschaftlichen" Seite betrachten, dann sind solche Foren ja ein Fundus von einer Art ungeordneten Buchkapiteln. Der Leser interessiert sich meist für das Thema des Kapitels und nicht so sehr für den Autor.

@snafu
Es ging mir Haupsächlich um Stilistische fragen (zumindest am anfang, jetzt hat sich es leider etwas ausgedehnt) und das würde ich einer Gruppe zuordnen und nicht zehn verschieden.
@lunar
Ok, am besten mach ich an den stellen wo ich mir nicht sicher bin mal ein paar geschwindigkeits test bzw. pass es der Sachlage an.
Im Prizip also so wie ich es bisher gemacht habe.
Es ging mir Haupsächlich um Stilistische fragen (zumindest am anfang, jetzt hat sich es leider etwas ausgedehnt) und das würde ich einer Gruppe zuordnen und nicht zehn verschieden.
@lunar
Ok, am besten mach ich an den stellen wo ich mir nicht sicher bin mal ein paar geschwindigkeits test bzw. pass es der Sachlage an.
Im Prizip also so wie ich es bisher gemacht habe.
IMHO hast du Lunar nicht verstanden. Er sprach im Wesentlichen davon, dass eine Ausnahme auch wirklich als ein seltener Fall angesehen werden sollte. Hinzu kommt, dass Exception-Handling relativ teuer ist. Dementsprechend solltest du eben nicht das beibehalten, was du bisher gezeigt hast.
Zur Vermeidung doppelter Lookups wurde ja schon `dict.get()` genannt, welches standardmäßig `None` bei einem nicht-existenten Schlüssel zurückliefert anstatt eine Ausnahme zu werfen. Für Objektattribute gibt es analog dazu `getattr(obj, attrname, None)`.
Es kommt aber sicher auf den Einzelfall an, ob man nach Versuch-und-Irrtum vorgeht oder explizit auf Bedingungen testet.
Zur Vermeidung doppelter Lookups wurde ja schon `dict.get()` genannt, welches standardmäßig `None` bei einem nicht-existenten Schlüssel zurückliefert anstatt eine Ausnahme zu werfen. Für Objektattribute gibt es analog dazu `getattr(obj, attrname, None)`.
Es kommt aber sicher auf den Einzelfall an, ob man nach Versuch-und-Irrtum vorgeht oder explizit auf Bedingungen testet.
Das meinte ich doch mit [...pass es der Sachlage an.]
Die ganzen try...excepts.. habe ich bisher nur einmal benutzt un nirgendwo sonst.
Diese Sachen am Anfang waren sachen die mir mir ständig wieder begegnet sind und wissen wollte ob es dazu etwas allgemein gültiges gibt.
und ja .get() hört sich gut an, aber bei den kleinen dicts die ich bisher hatte wäre eine doppelte prüfung mit "in" sowieso nicht aufgefallen in der Zeit.
So damit ihr mir nochmal sagen könnt das ich falsch liege fasse ich das mir hier nochmal zusammen.
- try...except... kostet Zeit
- sind aber Prinzipiell in Python erwünscht
- sollten aber nicht bei zu häufigen auftreten der Exceptions nicht genutz werden, wenn man eine andere Möglichkeit hat
- "in" statement um zuprüfen ob sich ein key in einer dict befindet nur dann Sinnvoll wenn man den Wert hinter dem Key nicht benötigt
- da man sonst zweimal auf die dict zugreifen muss
- also .get() nutzen
so ungefähr ?
Die ganzen try...excepts.. habe ich bisher nur einmal benutzt un nirgendwo sonst.
Diese Sachen am Anfang waren sachen die mir mir ständig wieder begegnet sind und wissen wollte ob es dazu etwas allgemein gültiges gibt.
und ja .get() hört sich gut an, aber bei den kleinen dicts die ich bisher hatte wäre eine doppelte prüfung mit "in" sowieso nicht aufgefallen in der Zeit.
So damit ihr mir nochmal sagen könnt das ich falsch liege fasse ich das mir hier nochmal zusammen.

- try...except... kostet Zeit
- sind aber Prinzipiell in Python erwünscht
- sollten aber nicht bei zu häufigen auftreten der Exceptions nicht genutz werden, wenn man eine andere Möglichkeit hat
- "in" statement um zuprüfen ob sich ein key in einer dict befindet nur dann Sinnvoll wenn man den Wert hinter dem Key nicht benötigt
- da man sonst zweimal auf die dict zugreifen muss
- also .get() nutzen
so ungefähr ?
Würde ich so nicht sagen. Sondern:Xynon1 hat geschrieben:- "in" statement um zuprüfen ob sich ein key in einer dict befindet nur dann Sinnvoll wenn man den Wert hinter dem Key nicht benötigt
- da man sonst zweimal auf die dict zugreifen muss
- also .get() nutzen
- get() lässt sich nicht immer einsetzen. Soll beispielsweise nur dann ein Wert ausgegeben werden, wenn es dazu einen Schlüssel im dict gibt, hilft get() nicht weiter.
- get() ist elegant und ich nutze es auch gerne; aber schneller als ein zweifacher Zugriff auf das dict ist es leider nicht.
- evtl. wäre hier noch defaultdict zu nennen; damit geht manches noch eleganter, aber nicht schneller (eher im Gegenteil).
Zusammenfassung: Muss es wirklich schnell gehen, dann ist die Prüfung mit "in" und das anschließende Abrufen oder Zuweisen des Wertes selbst bei ziemlich großen dicts in der Regel die beste Lösung.
Kommt es nicht so sehr auf die Performance an, sind get() und defaultdict auf jeden Fall eine Überlegung wert.