Magisches Verhalten in Perl und Python
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Die ganze Sache in Perl ist, dass überhaupt in Perl Variablen ohne explizite Zuweisung durch den Programmierer Werte annehmen - egal in welchem Scope. Sowas will ich wirklich, wirklich nicht in Python sehen. Wenn beim matchen mir irgendwelche Variablen erstellt werden, woher will ich wissen, ob nicht bei anderen Dingen noch mehr Variablen gefüllt werden? Oder gar noch andere Dinge passieren?
Ja, das ist eine Sache der Philosophie. Pythons ist "Explicit ist better than implicit" und so will ich meine Sprache auch haben - optimalerweise ohne Ausnahmen. Das Perl nicht so ist und damit gut fährt mag ja sein, das bezweifle ich gar nicht. Aber ich mag das nicht so haben, nutze also Perl nicht.
Ja, das ist eine Sache der Philosophie. Pythons ist "Explicit ist better than implicit" und so will ich meine Sprache auch haben - optimalerweise ohne Ausnahmen. Das Perl nicht so ist und damit gut fährt mag ja sein, das bezweifle ich gar nicht. Aber ich mag das nicht so haben, nutze also Perl nicht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Wenn ich "$1.." möchte, werden sie belegt. Meine Entscheidung.
Wenn ich den Match in Python möchte, werden ObjektVariablen gesetzt, auch wenn die Namen magischerweise nicht sichtbar werden.
Weniger Magisch?
Wenn ich den Match in Python möchte, werden ObjektVariablen gesetzt, auch wenn die Namen magischerweise nicht sichtbar werden.
Weniger Magisch?
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Was für Objektvariablen?PmanX hat geschrieben:Wenn ich "$1.." möchte, werden sie belegt. Meine Entscheidung.
Wenn ich den Match in Python möchte, werden ObjektVariablen gesetzt, auch wenn die Namen magischerweise nicht sichtbar werden.
Weniger Magisch?
Der Match ist ein Objekt vom Typ MatchObject, der von den re.find/search/etc.-Methoden zurückgegeben wird.
Das Matchobjekt hat Instanzvariablen, und die hat es ab seiner Erzeugung. Also: Selbstverständlich weniger magisch.
`eine_komische_funktion()` in dem Python-Beispiel steht für den Regulären Ausdruck in Perl. Also ist Dein Beispiel hier falsch. Das nach der Ausführung von ``$x =~ /(ab)/`` innerhalb der Funktion plötzlich $1..$n und $` und $' auf magische Weise mit Werten belegt sind, was sie vorher nicht waren, ist die Überraschung die man dem Ausdruck so nicht ansieht.PmanX hat geschrieben:Code: Alles auswählen
#!/usr/bin/perl -w sub eine_komisch_funktion { my $x = 'aabbaa'; print "Inhalt von \$1: $1 Inhalt von \$`: $` Inhalt von \$': $'\n" if ($x =~ /(ab)/); return 1; } eine_komisch_funktion(); print $1; print $`; print $';
Und wenn man vorher `$1` mit etwas belegt hat und das hinterher benutzen will, fällt man auf die Nase. Das kann einem bei Python nicht passieren: Egal welche Namen ich vorher an was auch immer gebunden habe, nach `match = re.search(…)` sind die immer noch an die selben Objekte gebunden und es sind auch weder im lokalen, noch im globalen Namensraum irgendwelche neuen Namen aufgetaucht. Die Ergebnisse bleiben schön im Namensraum des `match`-Objektes wo sie niemandem auf die Zehen treten.
PmanX, das schöne an Python ist seine Konsistenz und das es wirklich leicht zu erlernen ist und 99%(?) explizit passiert und daher leicht zu durchschauen ist. Solche Konstrukte die etwas implizit tun gehören nicht zu Pythons Philosophie [1]. Aber vielleicht habe ich ja Python auch nicht verstanden
[1] Auch wenn es durchaus Wege gibt in Python diese Regel zu brechen.
Und jetz mal in Python:
Die Ausgabe ist die gleiche. Und hier wir nichts auf Magische weise erzeugt, wie in der Perl Variante, sondern alles explizit.
[1] Auch wenn es durchaus Wege gibt in Python diese Regel zu brechen.
Ja weniger magisch Es werden, keine Variablen auf magischer weise erzeugt wie in Perl.PmanX hat geschrieben:Wenn ich "$1.." möchte, werden sie belegt. Meine Entscheidung.
Wenn ich den Match in Python möchte, werden ObjektVariablen gesetzt, auch wenn die Namen magischerweise nicht sichtbar werden.
Weniger Magisch?
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "<foo>blubb</bar>(foobar)";
print "$foobar\n";
$foobar =~ /<\/bar>/;
# Huch was ist den das? Wo kommt den $', $` und$& her? Nicht magisch?!
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
#<foo>blubb</bar>(foobar)
#post: (foobar)
#pre: <foo>blubb
#this: </bar>
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
foobar = "<foo>blubb</bar>(foobar)";
print foobar
m = re.search(r'(<\/bar>)', foobar)
_1, _2 = m.span()
print "post: %s" %foobar[_2:]
print "pre: %s" % foobar[:_1]
print "this: %s" % m.group()
#<foo>blubb</bar>(foobar)
#post: (foobar)
#pre: <foo>blubb
#this: </bar>
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Objektvariablen != Instanzvariablen
Python ist für Götter
EDIT:
[friedl]Ein erfolgreiches Matching oder eine Substitution setzt (!= erzeugt) eine Reihe von speziellen Variablen ...
Diese Variablen ändern sich nie bei einem erfolgreichen Matching-Versuch, und sie werden immer gesetzt, wenn ein Treffer gefunden wird[/friedl]
Python ist für Götter
EDIT:
[friedl]Ein erfolgreiches Matching oder eine Substitution setzt (!= erzeugt) eine Reihe von speziellen Variablen ...
Diese Variablen ändern sich nie bei einem erfolgreichen Matching-Versuch, und sie werden immer gesetzt, wenn ein Treffer gefunden wird[/friedl]
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Ich hatte eine Funktion benutzt.BlackJack hat geschrieben:`eine_komische_funktion()` in dem Python-Beispiel steht für den Regulären Ausdruck in Perl. Also ist Dein Beispiel hier falsch. Das nach der Ausführung von ``$x =~ /(ab)/`` innerhalb der Funktion plötzlich $1..$n und $` und $' auf magische Weise mit Werten belegt sind, was sie vorher nicht waren, ist die Überraschung die man dem Ausdruck so nicht ansieht.PmanX hat geschrieben:Code: Alles auswählen
#!/usr/bin/perl -w sub eine_komisch_funktion { my $x = 'aabbaa'; print "Inhalt von \$1: $1 Inhalt von \$`: $` Inhalt von \$': $'\n" if ($x =~ /(ab)/); return 1; } eine_komisch_funktion(); print $1; print $`; print $';
Und wenn man vorher `$1` mit etwas belegt hat und das hinterher benutzen will, fällt man auf die Nase. Das kann einem bei Python nicht passieren: Egal welche Namen ich vorher an was auch immer gebunden habe, nach `match = re.search(…)` sind die immer noch an die selben Objekte gebunden und es sind auch weder im lokalen, noch im globalen Namensraum irgendwelche neuen Namen aufgetaucht. Die Ergebnisse bleiben schön im Namensraum des `match`-Objektes wo sie niemandem auf die Zehen treten.
Code: Alles auswählen
... =~ m/../ ist ein Operator
Ach das ist doch Haarspalterei:PmanX hat geschrieben: [friedl]Ein erfolgreiches Matching oder eine Substitution setzt (!= erzeugt) eine Reihe von speziellen Variablen ...
[...]
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "bin leer";
print "$foobar\n";
$foobar =~ /<\/bar>/;
# Huch was ist den das? Wo kommt den $', $` und$& her? Nicht magisch?!
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
Code: Alles auswählen
bin leer
Use of uninitialized value in concatenation (.) or string at foobar.pl line 11.
post:
Use of uninitialized value in concatenation (.) or string at foobar.pl line 12.
pre:
Use of uninitialized value in concatenation (.) or string at foobar.pl line 13.
this:
Ein anderes Inkonsistentes verhalten ist auch $errno, das je nach Kontext als integer oder string interpretiert werden kann.
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Wo ist hier ein erfolgreiches Matching?sape hat geschrieben:Ach das ist doch Haarspalterei:PmanX hat geschrieben: [friedl]Ein erfolgreiches Matching oder eine Substitution setzt (!= erzeugt) eine Reihe von speziellen Variablen ...
[...]Code: Alles auswählen
#!/usr/bin/perl use strict; use warnings; my $foobar = "bin leer"; print "$foobar\n"; $foobar =~ /<\/bar>/; # Huch was ist den das? Wo kommt den $', $` und$& her? Nicht magisch?! print "post: $'\n"; print "pre: $`\n"; print "this: $&\n";
Wie man sieht ist $', $`, $& garnicht vorhanden bzw. initialisiert bei einem nicht erfolgreichen match. Und ob die nun erzeugt werden oder gesetzt werden ist in dem Fall irrelevant, weil ein unerwartetes Verhalten auftritt. -> Erwarten würde ich in jeden Fall das dann eben stattdessen empty strings ausgegeben werden, weil ich davon ausgehen das in jeden Fall $', $`, $& erzeugt wird oder von mir aus auch gesetztCode: Alles auswählen
bin leer Use of uninitialized value in concatenation (.) or string at foobar.pl line 11. post: Use of uninitialized value in concatenation (.) or string at foobar.pl line 12. pre: Use of uninitialized value in concatenation (.) or string at foobar.pl line 13. this:
Ein anderes Inkonsistentes verhalten ist auch $errno, das je nach Kontext als integer oder string interpretiert werden kann.
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Sorry, kann ich nur zurückgeben. Deine zitierte Zeile beschreibt doch Dein Problem.sape hat geschrieben:Liest du eigentlich was ich schreibe?PmanX hat geschrieben:[...]
Wo ist hier ein erfolgreiches Matching?
Warum, frage ich, sollen die Variablen bei einem erfolglosen Matching gesetzt werden?
EDIT:
Warum ist es Haarspalterei, wenn stets von magischer Erzeugung von Variablen gesprochen wird, die nicht erzeugt werden?
Sie sind entweder undefiniert oder mit dem Leerstring besetzt.
Beides ist FALSE und läßt sich wunderbar abfragen.
Zuletzt geändert von PmanX am Samstag 10. Februar 2007, 20:47, insgesamt 1-mal geändert.
Da ist keines, also sind auch die Variablen nicht da. Wäre eines da gewesen, dann wären die Variablen erzeugt worden. Was Du abgestritten hast mit dem Hinweis das setzen != erzeugen sei.PmanX hat geschrieben:Wo ist hier ein erfolgreiches Matching?
Und das es sich bei dem "matchen" um einen Operator statt eine Funktion handelt, ist irrelevant. Ausser das es bei Operatoren implizite Vorrangregeln gibt, ist so ein Operator auch nur ein Ersatz für einen Funktionsaufruf.
Ganz genau das wollte ich aussagen.BlackJack hat geschrieben:Da ist keines, also sind auch die Variablen nicht da. Wäre eines da gewesen, dann wären die Variablen erzeugt worden. Was Du abgestritten hast mit dem Hinweis das setzen != erzeugen sei.PmanX hat geschrieben:Wo ist hier ein erfolgreiches Matching?
[...]
Und mehr gibt es, denke ich, dazu auch nicht zu sagen.
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Falsch. Die Variablen sind da.BlackJack hat geschrieben:Da ist keines, also sind auch die Variablen nicht da. Wäre eines da gewesen, dann wären die Variablen erzeugt worden. Was Du abgestritten hast mit dem Hinweis das setzen != erzeugen sei.PmanX hat geschrieben:Wo ist hier ein erfolgreiches Matching?
Wenn es um den Gültigkeitsbereich von Variablen geht, ist es für mich nicht irrelevant.BlackJack hat geschrieben: Und das es sich bei dem "matchen" um einen Operator statt eine Funktion handelt, ist irrelevant. Ausser das es bei Operatoren implizite Vorrangregeln gibt, ist so ein Operator auch nur ein Ersatz für einen Funktionsaufruf.
Wie ich im Codebeispiel gezeigt hatte, besitzen die magischen Variablen außerhalb der Funktion EDIT: keinen definierten Wert.
Ja, stimmt ich vergaß das es diese inkonsistente art in Perl gab.PmanX hat geschrieben:[...]
Sie sind entweder undefiniert oder mit dem Leerstring besetzt.
Beides ist FALSE und läßt sich wunderbar abfragen.
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "bin leer";
#print "$foobar\n";
$foobar =~ /<\/bar>/;
# Huch was ist den das? Wo kommt den $', $` und$& her? Nicht magisch?!
if ($' or $` or $&){
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
} else {print "blubb";};
Ein print $` bringt ein "Use of uninitialized value in concatenation (.) or string at foobar.pl line 11.".
Ok, sie werden nicht erzeugt sondern "initialisiert" (Was aber schon ein Widerspruch zum aufgezeigten verhalten ist).
Und sowas willst du ernsthaft in Python haben? Nein danke. Wenn du sowas brauchst bleib doch bei Perl Ich nutze es auch oft für quick'n'dirty Scripts
Hey, schön finde ich ja das Verhalten:
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "bin nicht leer </bar>";
#print "$foobar\n";
$foobar =~ /<\/bar>/;
# Huch was ist den das? Wo kommt den $', $` und$& her? Nicht magisch?!
if ($'){
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
} else {print "blubb";};
ok machen wir daraus ``if ($' or $' eq ''){``: Super geht doch.
Aber moment:
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "bin nicht leer";
#print "$foobar\n";
$foobar =~ /<\/bar>/;
# Huch was ist den das? Wo kommt den $', $` und$& her? Nicht magisch?!
if ($' or $' eq ''){
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
} else {print "blubb";};
Code: Alles auswählen
Use of uninitialized value in string eq at foobar.pl line 11.
Also muss man dann doch ``if ($' or $` or $&)`` wie im ersten listning nutzen damit bei einem erfolgreichen match auf jedenfall das if... ausgeführt wird.
Soll ich weiter machen? Ich Könnte den ganzen Abend von der Inkonsistenz von Perl berichten...
lg
Ist ja schön und gut, aber Du hast nicht verstanden was dieses Script aussagen sollte. Es sollte verdeutlichen das da aus heiterem Himmel auf einmal ``foo`` erzeugt wird mit einer Funktion/Operator/etc... und man danach auf ``foo`` zurückgreifen kann aus dem global namespace (Ok, in dem beispiel der space von __builtins__ der aber global erreichbar ist oder so ähnlich -- Tut aber nichts zur Sache).PmanX hat geschrieben:Wenn es um den Gültigkeitsbereich von Variablen geht, ist es für mich nicht irrelevant.BlackJack hat geschrieben: Und das es sich bei dem "matchen" um einen Operator statt eine Funktion handelt, ist irrelevant. Ausser das es bei Operatoren implizite Vorrangregeln gibt, ist so ein Operator auch nur ein Ersatz für einen Funktionsaufruf.
Wie ich im Codebeispiel gezeigt hatte, besitzen die magischen Variablen außerhalb der Funktion EDIT: keinen definierten Wert.
So, das =~ /.../ zeigt ein ähnliches Verhalten nach außen hin. Ob die nun initialisiert werden oder erzeugt ist irrelevant für mich. Es passiert dort etwas "magisches" oder besser gesagt implizites, das wir in Python nicht haben wollen.
Mit den Funktionen in Perl oder den Pseudo-Klassen fange ich mal lieber erst garnicht an...
Oh bitte, dann gibt es in jedem Perl-Skript Milliarden von Variablen. Die sind alle da, nur eben nicht initialisiert. Das ist jetzt nicht wirklich Dein Argument, oder?PmanX hat geschrieben:Falsch. Die Variablen sind da.BlackJack hat geschrieben:Da ist keines, also sind auch die Variablen nicht da. Wäre eines da gewesen, dann wären die Variablen erzeugt worden. Was Du abgestritten hast mit dem Hinweis das setzen != erzeugen sei.PmanX hat geschrieben:Wo ist hier ein erfolgreiches Matching?
Um diese Funktion geht es gar nicht. Es geht um das "matchen" das in Perl ausserhalb des Ausdrucks in dem es passiert den Zustand von Variablen verändert, die nicht explizit erwähnt werden. Denn innerhalb der Funktion in Deinem Beispiel passiert genau das. Eine Magie die es bei `re` in Python nicht gibt.Wenn es um den Gültigkeitsbereich von Variablen geht, ist es für mich nicht irrelevant.BlackJack hat geschrieben: Und das es sich bei dem "matchen" um einen Operator statt eine Funktion handelt, ist irrelevant. Ausser das es bei Operatoren implizite Vorrangregeln gibt, ist so ein Operator auch nur ein Ersatz für einen Funktionsaufruf.
Wie ich im Codebeispiel gezeigt hatte, besitzen die magischen Variablen außerhalb der Funktion EDIT: keinen definierten Wert.
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
Ich sehe keinen entscheidenen Unterschied, ob Python eine neue Match-Instanz bildet oder Perl die Variablen initialisiert.BlackJack hat geschrieben: Oh bitte, dann gibt es in jedem Perl-Skript Milliarden von Variablen. Die sind alle da, nur eben nicht initialisiert. Das ist jetzt nicht wirklich Dein Argument, oder?
Die Variablen stehen innerhalb des Blockes zur Verfügung und genau das erwarte ich auch.BlackJack hat geschrieben: Um diese Funktion geht es gar nicht. Es geht um das "matchen" das in Perl ausserhalb des Ausdrucks in dem es passiert den Zustand von Variablen verändert, die nicht explizit erwähnt werden. Denn innerhalb der Funktion in Deinem Beispiel passiert genau das. Eine Magie die es bei `re` in Python nicht gibt.
- birkenfeld
- Python-Forum Veteran
- Beiträge: 1603
- Registriert: Montag 20. März 2006, 15:29
- Wohnort: Die aufstrebende Universitätsstadt bei München
Es ist jedenfalls ein Unterschied da. Wie man den wahrnimmt entscheidet dann eben auch, was man an einer Sprache gut bzw. schlecht findet.PmanX hat geschrieben:Ich sehe keinen entscheidenen Unterschied, ob Python eine neue Match-Instanz bildet oder Perl die Variablen initialisiert.BlackJack hat geschrieben: Oh bitte, dann gibt es in jedem Perl-Skript Milliarden von Variablen. Die sind alle da, nur eben nicht initialisiert. Das ist jetzt nicht wirklich Dein Argument, oder?
[/quote]Die Variablen stehen innerhalb des Blockes zur Verfügung und genau das erwarte ich auch.BlackJack hat geschrieben: Um diese Funktion geht es gar nicht. Es geht um das "matchen" das in Perl ausserhalb des Ausdrucks in dem es passiert den Zustand von Variablen verändert, die nicht explizit erwähnt werden. Denn innerhalb der Funktion in Deinem Beispiel passiert genau das. Eine Magie die es bei `re` in Python nicht gibt.
Ich erwarte dagegen halt, dass ohne eine explizite Zuweisung meinerseits in einem Scope nicht einfach so Variablen "auftauchen". Aber wie oben gesagt, das ist Gewöhnungssache.
-
- User
- Beiträge: 123
- Registriert: Donnerstag 25. Januar 2007, 13:50
- Wohnort: Germany.BB.LOS
- Kontaktdaten:
sape:
Welche Variable soll hier wahr werden?
Dir ist aufgefallen, dass der Match am Ende des Strings erfolgt. Warum soll das wahr werden?
Dir ist aufgefallen, dass der Block ausgeführt wird. $' eq '' So könnte man wohl Deine unsinnigen Beispiele weiter kommentieren.
Code: Alles auswählen
#!/usr/bin/perl
use strict; use warnings;
my $foobar = "bin leer";
print "$foobar\n";
$foobar =~ /<\/bar>/;
if ($' or $` or $&){
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
} else { print "blubb" }
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "bin nicht leer </bar>";
$foobar =~ /<\/bar>/;
if ($'){
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
} else {print "blubb";};
Code: Alles auswählen
#!/usr/bin/perl
use strict;
use warnings;
my $foobar = "bin nicht leer";
$foobar =~ /<\/bar>/;
if ($' or $' eq ''){
print "post: $'\n";
print "pre: $`\n";
print "this: $&\n";
} else {print "blubb";};