Seite 1 von 4

Magisches Verhalten in Perl und Python

Verfasst: Mittwoch 7. Februar 2007, 22:30
von sunmountain
Edit (Leonidas): Vom Thread "Code Converter?" abgetrennt.
birkenfeld hat geschrieben: ... in Perl manche Konstruktionen teilweise beim Ausführen erst ihre Bedeutung festlegen ...
Wie z.B. so 'einfache' Dinge wie Skalare oder Listen Kontexte ...
... dafür vermisse ich in Python den ~= Operator
und $1 .. $n

Edit (Leonidas): Vom Thread "Code Converter?" abgetrennt.

Re: Ja,

Verfasst: Donnerstag 8. Februar 2007, 14:25
von Leonidas
sunmountain hat geschrieben:... dafür vermisse ich in Python den ~= Operator
Nutzt du si häufig reguläre Ausdrücke in Python wie in Perl?
sunmountain hat geschrieben:und $1 .. $n
Das entspricht nicht der Python-Idee und wird es hoffentlich nie geben. Variablen die sich magisch mit Werten füllen *schauder*.

Re: Ja,

Verfasst: Donnerstag 8. Februar 2007, 19:10
von PmanX
Leonidas hat geschrieben:Das entspricht nicht der Python-Idee und wird es hoffentlich nie geben. Variablen die sich magisch mit Werten füllen *schauder*.
So schlecht, dass man mit re und groups() große Teile dieser Magie ins Boot genommen hat :wink:

Re: Ja,

Verfasst: Donnerstag 8. Februar 2007, 19:26
von Luzandro
PmanX hat geschrieben:So schlecht, dass man mit re und groups() große Teile dieser Magie ins Boot genommen hat :wink:
Ich seh hier keinen Zusammenhang - wo passiert da irgendwas magisches oder tauchen plötzlich irgendwelche variablen auf?

Re: Ja,

Verfasst: Donnerstag 8. Februar 2007, 19:31
von Leonidas
Luzandro hat geschrieben:
PmanX hat geschrieben:So schlecht, dass man mit re und groups() große Teile dieser Magie ins Boot genommen hat :wink:
Ich seh hier keinen Zusammenhang - wo passiert da irgendwas magisches oder tauchen plötzlich irgendwelche variablen auf?
Ich sehe da ebensowenig Magie. Reguläre Ausdrücke haben ein genau festgelegtes Verhalten und geben immer Treffer beim Matchen zurück die man abfragen kann. Es werden keine externen Variablen modifiziert, weder globale noch so etwas wie re.match_1 oder ähnliches.

Verfasst: Donnerstag 8. Februar 2007, 19:33
von PmanX

Code: Alles auswählen

>>> p = re.compile('(a(b)c)d')
>>> m = p.match('abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abc'
>>> m.group(2)
'b'
sehe ich nicht so.

Verfasst: Donnerstag 8. Februar 2007, 19:43
von Luzandro
Du sprichst hier von regulären Ausdrücken und dass du von deinem Match-Objekt die einzelnen gematchten Gruppen abfragen kannst, was ja wohl auch der Sinn davon ist - was Leonidas kritisiert hat, ist dass sich bei Perl durch eine Aktion irgendwelche anderen globalen Werte ändern.

Verfasst: Donnerstag 8. Februar 2007, 19:57
von PmanX
Wo ist $1 .. $n global?

Verfasst: Donnerstag 8. Februar 2007, 20:03
von mitsuhiko
Luzandro hat geschrieben:...irgendwelche anderen globalen Werte ändern.
thread lokale...

Verfasst: Donnerstag 8. Februar 2007, 20:18
von BlackJack
Auf jeden Fall sind sie nicht lokal zur re-Funktion in Perl. Die nicht einmal eine Funktion sondern ein eigenes Syntax-Konstrukt ist. Alles sehr magisch. Bei Python hat man Objekte und Methoden mit der gleichen Semantik wie alle anderen Objekte und Methoden. Kein spezielles Syntaxkonstrukt, keine magischen Variablen, also weniger das man neben den, sowieso schon nicht ganz einfachen, regulären Ausdrücken lernen und behalten muss.

Verfasst: Donnerstag 8. Februar 2007, 20:42
von PmanX
Ja gut, man braucht eine Methode um den eingefangenen String abzuholen.
Wenn die "Magie" nicht wäre, müßte man den RegEx zweimal ansetzen. Matcht & Klammern auslesen.

**Edit**
Die "magischen Variablen" werden im nächsten Block durch den aktuellen Match überdeckt. Ich hatte da nie Probleme.

Rein aus Interresse schaue ich mir seit einigen Tagen Python an. Aus heutiger Sicht kann ich sagen: Für komplexe, umfangreiche Programme ist Python eine gute Wahl. Für String- Textverarbeitung will ich die RegEx und Magie von Perl!

Verfasst: Freitag 9. Februar 2007, 20:42
von Joghurt
Was Leonidas meint, ist das folgendes unpythonic ist

Code: Alles auswählen

>>> foo
NameError: 'foo' is not defined
>>> IrgendeinekomischeFunktion()
>>> foo[4]
42

Verfasst: Samstag 10. Februar 2007, 15:03
von PmanX
Da fehlt mir die Fantasie. :?:

Verfasst: Samstag 10. Februar 2007, 15:55
von sape
PmanX hat geschrieben:Da fehlt mir die Fantasie. :?:
Warum?
``foo`` existier nicht, was durch die exception ``NameError:`` angedeutet wird. Nun wird ``IrgendeinekomischeFunktion`` aufgeruffen die auf "magischerweise" ``foo`` in den globalen namenspace erzeugt. Danach ist ``foo`` existent und man kann darauf auf einmal zugreifen. Sehr Magisch oder? So änlich verhält es sich auch mit $`, $', etc bei Perl beim Gebrauch von regex (/.../).

Ich finde Joghurt hat das sehr anschaulich dargestellt.

Verfasst: Samstag 10. Februar 2007, 16:23
von PmanX
In welchen Namensraum?

Code: Alles auswählen

#!/usr/bin/perl -w

sub eine_komisch_funktion {
	my $x = 'aabbaa';
	print "Inhalt von \$1: $1\n" if ($x =~ /(ab)/);
	return 1;
}

eine_komisch_funktion;

print $1
$ ./test.pl
Inhalt von $1: ab
Use of uninitialized value in print at test.pl line 11.

Verfasst: Samstag 10. Februar 2007, 16:41
von sape
So z.B.:

Code: Alles auswählen

def IrgendeinekomischeFunktion():
    exec ('__builtins__.foo= [1,2,3]')

try:
    foo
except NameError, error:
    print error

IrgendeinekomischeFunktion()
print foo # -> [1, 2, 3]
Auf einmal gibt es auf "Magischerweise" ``foo``.

EDIT:
Und in Perl wird ja auf "Magischerweise" $`, $', auch erzeugt nach dem Gebrauch von regex.

Verfasst: Samstag 10. Februar 2007, 16:46
von Leonidas
sape hat geschrieben:

Code: Alles auswählen

def IrgendeinekomischeFunktion():
    exec ('__builtins__.foo= [1,2,3]')
Huch?

Code: Alles auswählen

def IrgendeinekomischeFunktion():
    __builtins__.foo = [1,2,3]

Verfasst: Samstag 10. Februar 2007, 16:56
von birkenfeld
sape hat geschrieben:So z.B.:

Code: Alles auswählen

def IrgendeinekomischeFunktion():
    exec ('__builtins__.foo= [1,2,3]')
Also in 2.x ist exec schon noch ein Statement, also keine Klammern.
Und wenn du exec nur einen String ohne globals- oder locals-Argument gibst, kannst du das auch gleich ohne exec schreiben.

Verfasst: Samstag 10. Februar 2007, 17:28
von sape
Leonidas hat geschrieben:
sape hat geschrieben:

Code: Alles auswählen

def IrgendeinekomischeFunktion():
    exec ('__builtins__.foo= [1,2,3]')
Huch?

Code: Alles auswählen

def IrgendeinekomischeFunktion():
    __builtins__.foo = [1,2,3]
birkenfeld hat geschrieben:[...]
Und wenn du exec nur einen String ohne globals- oder locals-Argument gibst, kannst du das auch gleich ohne exec schreiben.
Ja, hab da auf die schnelle nicht darauf geachtet, weil ich das ursprünglich anders machen wollte...

...

Verfasst: Samstag 10. Februar 2007, 17:45
von PmanX

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 $';

Code: Alles auswählen

./test.pl
Inhalt von $1: ab Inhalt von $`: a Inhalt von $': baa
Use of uninitialized value in print at test.pl line 11.
Use of uninitialized value in print at test.pl line 12.
Use of uninitialized value in print at test.pl line 13.
***Edit*** Noch klarer!

Code: Alles auswählen

#!/usr/bin/perl -w

{
	my $x = 'aabbaa';
	print "Inhalt von \$1: $1 Inhalt von \$`: $` Inhalt von \$': $'\n" if ($x =~ /(ab)/);
}

print $1;
print $`;
print $';

Code: Alles auswählen

./test.pl
Inhalt von $1: ab Inhalt von $`: a Inhalt von $': baa
Use of uninitialized value in print at test.pl line 8.
Use of uninitialized value in print at test.pl line 9.
Use of uninitialized value in print at test.pl line 10.