Magisches Verhalten in Perl und Python

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.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Sonntag 11. Februar 2007, 09:44

Hi

Es geht nicht darum ob man das Resultat (das Matchobjekt) kennt oder nicht, sondern nur um die Zuweisung geht es.

In Python sieht man durch das "=", dass dem Namen "m" das Resultat des regulären Ausdruckes zugewiesen wird.

Code: Alles auswählen

m = re.search('(.*)', 'foo') # m wird klar definiert


In Perl dagegen wird keine Zuweisung gemacht, nur der reguläre Ausdruck wird gemacht. Danach sind im Namensraum auf einmal $' $` und $& gesetzt, ohne dass diese in dem aktuellen Block jemals zugewiesen wurden.

Code: Alles auswählen

$foobar =~ /<\/bar>/;

Wo seh ich in diesem Block die Zuweisung der $' $` $& Variabeln? Diese wurden in einem tieferen Block erstellt, somit weiterhin gültig anstatt nur im Block in dem diese definiert wurden.

Das ist die Magie.

Gruss
BlackJack

Beitragvon BlackJack » Sonntag 11. Februar 2007, 10:18

PmanX hat geschrieben:

Code: Alles auswählen

>>> m=re.search('(.*)', 'foo')
>>> m.group(1)
'foo'
>>> m.group(0)
'foo'
>>>

Etwas mehr passiert hier schon, wenn das Resultat nicht weggeworfen wird.
EDIT:
Da man die Werte ja will, sieht der Unterschied für mich so aus:
Python)
Ich muß die Methoden kennen um die Variablen auszulesen.
Perl)
Ich muß die handvoll ma.. Variablen kennen.


Also doch Magie, auch wenn Du's nicht ausschreiben magst. Es geht um den Namensraum in dem die dokumentierten Namen sich befinden bzw. auftauchen. Bei Perl muss man die Dokumentation kennen um sich nicht fragen zu müssen was `$1` denn eigentlich ist und welche der vorherigen Zeilen das wohl gesetzt haben mag. Bei Python ist sofort ersichtlich wo `match` seinen Wert herbekommt und das `group()` etwas mit dem `match` zu tun hat. Und wenn man die Begrifflichkeiten von regulären Ausdrücken kennt, weiss man auch schon was mit der Zeile höchstwahrscheinlich gemeint ist.

Dynamische Sichtbarkeitsbereiche werden von den meisten Pythonistas als unsauber angesehen, weil Funktionen, die im Namensraum des Aufrufers machen können was sie wollen, schnell zu Problemen führen können und Quelltext der so etwas benutzt schwerer zu durchschauen ist.
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Beitragvon PmanX » Sonntag 11. Februar 2007, 14:29

BlackJack hat geschrieben:Also doch Magie, auch wenn Du's nicht ausschreiben magst. Es geht um den Namensraum in dem die dokumentierten Namen sich befinden bzw. auftauchen. Bei Perl muss man die Dokumentation kennen um sich nicht fragen zu müssen was `$1` denn eigentlich ist und welche der vorherigen Zeilen das wohl gesetzt haben mag. Bei Python ist sofort ersichtlich wo `match` seinen Wert herbekommt und das `group()` etwas mit dem `match` zu tun hat. Und wenn man die Begrifflichkeiten von regulären Ausdrücken kennt, weiss man auch schon was mit der Zeile höchstwahrscheinlich gemeint ist.

Dynamische Sichtbarkeitsbereiche werden von den meisten Pythonistas als unsauber angesehen, weil Funktionen, die im Namensraum des Aufrufers machen können was sie wollen, schnell zu Problemen führen können und Quelltext der so etwas benutzt schwerer zu durchschauen ist.


Die Auseinandersetzung mit den regulären Ausdrücken von Perl hat ja was Positives.
Von den 5 Variablen [code=]$1, $2, $3 .. $n # erste, zweite .. Klammerpaar
$+ # Kopie des letzten Klammerpaars
$& # Text der auf gesamte Regex paßt
$` # Kopie des Textes davor
$' # Kopie des Textes nach dem Treffer[/code]habe ich bisher nur [code=]$1 .. $n und $+[/code] benutzt. Diese werden nach einem erfolgreichen Matching im aktuellen Block gesetzt und sind dort gültig. Wenn man diese zwei Sätze nicht versteht, sollte man die Finger von regulären Ausdrücken lassen.
Und ich wage zu behaupten, dass nur ein kleiner Teil der Pythonistas re komplett verstanden hat.

Dieses definierte Verhalten kann man nutzen. Es fällt niemandem auf den Fuß, wenn er es läßt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 11. Februar 2007, 14:37

Es gibt da zwei Ebenen, die man verstehen muss: zum einen die regulären Ausdrücke selbst, zum anderen die API zur Nutzung.

Das erste ist das, was den meisten anfangs Schwierigkeiten bereitet. Hat man REs verstanden, braucht man nur noch die Funktionen und Klassen des re-Moduls kennen, und die verhalten sich wie die in allen anderen Modulen auch.

Freilich versteht man Perls Verhalten auch nicht erst Wochen später, es geht hier hauptsächlich um die Philosophie.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Sonntag 11. Februar 2007, 14:49

PmanX hat geschrieben:Die Auseinandersetzung mit den regulären Ausdrücken von Perl hat ja was Positives.

Wir reden nicht von Regulären Ausdrücken sondern vom Konzept eines dynamischen Scopes.

Von den 5 Variablen [...] habe ich bisher nur [code=]$1 .. $n und $+[/code] benutzt. Diese werden nach einem erfolgreichen Matching im aktuellen Block gesetzt und sind dort gültig.

Ich geb zu, dass ich von Perl keine Ahnung habe, aber das selbe Konzept haben wir in Ruby auch. Dort verwende ich fast ausschließlich nur $1 - $9, sowie $~, der den letzten Match als MatchData objekt enthält:

Code: Alles auswählen

irb(main):001:0> %r(<([a-z]+)>(.*?)</\1>) =~ "<peter>max and moritz</peter>"
=> 0
irb(main):002:0> $1
=> "peter"
irb(main):003:0> $2
=> "max and moritz"
irb(main):004:0> $~.begin(0)
=> 0
irb(main):005:0> $~.end(0)
=> 29

Damit lassen sich dann tatsächlich auch so tolle Konstrukte bauen wie:

Code: Alles auswählen

return other[$~.start(0)..$~.end(0)] if /.../ =~ blah

(das impliziert halt, dass rubys true/false konzept blöd ist ^^)

Aber weißt du was? Ich finde es deswegen nicht besser. $foobar Variablen sind in Ruby wenigstens durch die Bank "vordefiniert", das heißt auf nicht deklarierte globals zuzugreifen resultiert in nil. Allerdings haben wir soetwas in Python nicht. Und ich sehe auch nur Probleme soetwas einzufügen.

Und mal ehrlich! Wer braucht soetwas?

Wenn man diese zwei Sätze nicht versteht, sollte man die Finger von regulären Ausdrücken lassen.

Dann lass die Finger davon.

Und ich wage zu behaupten, dass nur ein kleiner Teil der Pythonistas re komplett verstanden hat.

Hast du es? Ich bezweilfe es. Und du wirst Recht haben. Die Anzahl der Personen die jeden Kniff der sre Bibliothek kennen wird verdammt klein sein. Gerade re.scanner ist mir nur aufgefallen als ich in den Sourcen nachgesehen habe.
TUFKAB – the user formerly known as blackbird
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Beitragvon PmanX » Sonntag 11. Februar 2007, 15:08

blackbird hat geschrieben:Und mal ehrlich! Wer braucht soetwas?

Wenn man diese zwei Sätze nicht versteht, sollte man die Finger von regulären Ausdrücken lassen.

Dann lass die Finger davon.

Und ich wage zu behaupten, dass nur ein kleiner Teil der Pythonistas re komplett verstanden hat.

Hast du es? Ich bezweilfe es. Und du wirst Recht haben. Die Anzahl der Personen die jeden Kniff der sre Bibliothek kennen wird verdammt klein sein. Gerade re.scanner ist mir nur aufgefallen als ich in den Sourcen nachgesehen habe.


Das ist der Punkt. Sich durch die Klassen durchzuwursten, macht es nicht handhabbarer.

Einige Pythonistas fühlen sich schnell angepinkelt, wenn man ihre Religion nicht teilt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 11. Februar 2007, 15:12

PmanX hat geschrieben:Das ist der Punkt. Sich durch die Klassen durchzuwursten, macht es nicht handhabbarer.

Darüber kann man sich natürlich wieder trefflich streiten ;)

Einige Pythonistas fühlen sich schnell angepinkelt, wenn man ihre Religion nicht teilt.

Ja, leider gibt es in jeder Community solche Eiferer. Seine Meinung darstellen, und dann leben und leben lassen wäre angebrachter.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Beitragvon PmanX » Sonntag 11. Februar 2007, 15:52

Full ACK.
Ein großes Kompliment an das Forum. So eine hilfsbereite Community erlebt man nicht oft.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Sonntag 11. Februar 2007, 15:55

PmanX hat geschrieben:Das ist der Punkt. Sich durch die Klassen durchzuwursten, macht es nicht handhabbarer.

Nein, aber wenn man von einem Matching ein Match Objekt zurückbekommt dann weiß man gleich was man damit anfangen kann. Wer würde auf die Idee Kommen, dass bei einem Matching irgendwelche obskuren Variablen belegt werden?

PmanX hat geschrieben:Einige Pythonistas fühlen sich schnell angepinkelt, wenn man ihre Religion nicht teilt.

Mal abgesehen davon hat diese Diskussion weniger mit Religion zu tun. Perls Verhalten ist an dieser Stelle magischer als das von Python. Das haben wir dir auf vier Seiten erklärt - wenn du es nicht einsiehst und stattdessen zur Syntax regulärer Ausdrücke ausweichst - kann man dir nicht helfen.

Wie blackbird sagte: es geht nicht so sehr um reguläre Ausdrücke sondern um Scopes die verändert werden. Ob das nun bei regulären Ausdrücken ist, oder etwas anderem ist in diesem Fall recht uninteressent. An regulären Ausdrücken kann man es nur eben gut demonstrieren.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Beitragvon BlackJack » Sonntag 11. Februar 2007, 16:42

PmanX hat geschrieben:Von den 5 Variablen [code=]$1, $2, $3 .. $n # erste, zweite .. Klammerpaar
$+ # Kopie des letzten Klammerpaars
$& # Text der auf gesamte Regex paßt
$` # Kopie des Textes davor
$' # Kopie des Textes nach dem Treffer[/code]habe ich bisher nur [code=]$1 .. $n und $+[/code] benutzt. Diese werden nach einem erfolgreichen Matching im aktuellen Block gesetzt und sind dort gültig. Wenn man diese zwei Sätze nicht versteht, sollte man die Finger von regulären Ausdrücken lassen.


Diese beiden Sätze habe ich verstanden. Und sie haben nichts mit regulären Ausdrücken im Speziellen zu tun. Das ist jetzt einfach *eine* Funktion (Operator) bei der sich in Perl dieses Verhalten zeigt, dass von der Funktion, die ja auch einen eigenen Namensraum besitzt, Variablen im Namensraum des Aufrufers verändert werden. Das habe ich schonmal geschrieben und habe so das Gefühl das Du das nicht so ganz erfasst hast.

Und ich wage zu behaupten, dass nur ein kleiner Teil der Pythonistas re komplett verstanden hat.


Hat zwar nichts mit dem Thema zu tun, aber ausser Friedl und einer handvoll anderer, trifft das wohl auf seeehr viele Menschen zu.

Dieses definierte Verhalten kann man nutzen. Es fällt niemandem auf den Fuß, wenn er es läßt.


Beim selbst benutzen nicht, aber wenn man Quelltext nachvollziehen möchte der dynamische Sichtbarkeitsbereiche verwendet, dann kann es schon problematisch werden. Mal vergleichen:

Code: Alles auswählen

# Achtung: "Pseudo-Python" mit dynamic scope.
def f():
    spam()
    ham()
    cheddar()
    print a, b   # Gibt 42 und 'Eric' aus.


Welche der drei Funktionsaufrufe, einzeln oder in Kombination, haben `a` und `b` gesetzt/verändert? Und gibt's vielleicht auch ein `c` oder `d` oder…

Code: Alles auswählen

def f():
    spam()
    x = ham()
    cheddar()
    print x.a, x.b  # Gibt 42 und 'Eric' aus.


Und nochmal die gleiche Frage.
lunar

Beitragvon lunar » Sonntag 11. Februar 2007, 17:14

PmanX hat geschrieben:Das ist der Punkt. Sich durch die Klassen durchzuwursten, macht es nicht handhabbarer.


Die implizite Zuweisung von Variablen ist aber nicht wirklich handlich ...

PmanX hat geschrieben:Einige Pythonistas fühlen sich schnell angepinkelt, wenn man ihre Religion nicht teilt.


Und Perlies sind natürlich immer neutral, objektiv und sachlich ...
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Beitragvon PmanX » Sonntag 11. Februar 2007, 17:22

Wenn ich mit einer bestimmten Klassen arbeiten möchte, muß ich auch die Dokumentation der entsprechenden Basisklassen kennen. Das erfordert eine Einarbeitung, die recht umfangreich sein kann.
Was bitteschön ist da der riesige Vorteil?
lunar

Beitragvon lunar » Sonntag 11. Februar 2007, 18:11

PmanX hat geschrieben:Wenn ich mit einer bestimmten Klassen arbeiten möchte, muß ich auch die Dokumentation der entsprechenden Basisklassen kennen. Das erfordert eine Einarbeitung, die recht umfangreich sein kann.
Was bitteschön ist da der riesige Vorteil?


Ich weiß ja nicht, mit welchen Modulen du dich rumschöägst, aber zumindest die Standardmodule haben selten komplexe Vererbungshierarchien...

Außerdem geht es doch gar nicht darum ... Dokumentation musst du sowieso lesen (oder willst du mir erzählen, du kannst jedes Perl-Modul ohne Doku benutzen?).

Hier geht es um die Tatsache, dass Perl implizite Zuweisungen vornimmt, die für den Leser des Codes nicht unbedingt sofort klar erkennbar sind. Python dagegen nimmt niemals implizite Zuweisungen vor, sondern verlangt immer explizite Ausdrücke zur Definition von Variablen. Anderweitiges Verhalten muss mittels des global Statements explizit verlangt werden. Der Vorteil liegt auf der Hand: Die Herkunft jeder einzelnen Variable ist sofort klar, selbst wenn man die Feinheiten der Sprache nicht beherrscht.
Bei Perl dagegen muss man den Code erstmal im Kopf "parsen", um die Herkunft impliziter Variablen zu klären ...
Benutzeravatar
Luzandro
User
Beiträge: 87
Registriert: Freitag 21. April 2006, 17:03

Beitragvon Luzandro » Sonntag 11. Februar 2007, 18:13

Und ich hatte schon gehofft, birkenfeld hätte endlich ein Schlusswort gefunden...

PmanX hat geschrieben:Wenn ich mit einer bestimmten Klassen arbeiten möchte, muß ich auch die Dokumentation der entsprechenden Basisklassen kennen. Das erfordert eine Einarbeitung, die recht umfangreich sein kann.
Was bitteschön ist da der riesige Vorteil?


Also das Argument mit der umfangreichen Einarbeitung in die Klassen finde ich jetzt schon etwas lächerlich - dem gegenüber ist die Einarbeitung gleich viel leichter, wenn ein Feature direkt in der Sprache verzahnt ist :roll:

Allerdings hat die Diskussion auch ursprünglich nur damit begonnen, dass es um etwas geht, was nicht zur Sprache passt - das hat nichts mit einer "Religion" zu tun, sondern es geht um konzeptionelle Fragen einer Programmiersprache und diese sollten möglichst konsistent sein. Das alleine hat noch nichts mit einer Wertung zu tun, auch wenn sich Python-Leute natürlich fragen, was denn bitte der Vorteil daran sein sollte, mit diesen Konzepten zu brechen und es _nicht_ so zu machen.
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Beitragvon PmanX » Sonntag 11. Februar 2007, 18:51

Luzandro hat geschrieben:Also das Argument mit der umfangreichen Einarbeitung in die Klassen finde ich jetzt schon etwas lächerlich - dem gegenüber ist die Einarbeitung gleich viel leichter, wenn ein Feature direkt in der Sprache verzahnt ist :roll:

Meine Schuld. Ich hätte dirkt auf BlackJack's

Code: Alles auswählen

# Achtung: "Pseudo-Python" mit dynamic scope.
def f():
    spam()
    ham()
    cheddar()
    print a, b   # Gibt 42 und 'Eric' aus.
eingehen sollen.
Luzandro hat geschrieben:Allerdings hat die Diskussion auch ursprünglich nur damit begonnen, dass es um etwas geht, was nicht zur Sprache passt - das hat nichts mit einer "Religion" zu tun, sondern es geht um konzeptionelle Fragen einer Programmiersprache und diese sollten möglichst konsistent sein. Das alleine hat noch nichts mit einer Wertung zu tun, auch wenn sich Python-Leute natürlich fragen, was denn bitte der Vorteil daran sein sollte, mit diesen Konzepten zu brechen und es _nicht_ so zu machen.

5 Variablen, den Match- und Substitutionsoperator zu kennen ist nicht weniger eingänglich, als die Funktionalität des Moduls re. Der objektorientierte Ansatz hat ganz sicher Vorteile, aber er ist nicht die eierlegende Wollmilchsau.

Wer ist online?

Mitglieder in diesem Forum: WhiteyW