[Python-de] Zuweisungen bei if?

Sebastian Wiesner lunaryorn at googlemail.com
Di Apr 10 17:05:13 CEST 2012


Am 10. April 2012 16:24 schrieb Thomas Rachel
<nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915 at spamschutz.glglgl.de>:
> Am 10.04.2012 13:28 schrieb Hartmut Goebel:
>
>> Am 10.04.2012 12:30, schrieb Diez B. Roggisch:
>>>
>>> Aber sei's drum. Nur solltest du mit dem _ aufpassen - afaik wird das als
>>> temporärer Name in List comprehensions verwandt - und damit könntest du in
>>> Probleme kommen, weil da was anderes drin ist als du erwartest.
>>
>>
>> *Dieses* Problem besteht allerdings nicht, da die temporärer Namen in
>> List Comprehensions `_[0]`, `_[1]`, usw. lauten.
>
>
> Versteh ich jetzt nicht ganz. Wenn ich folgendes mache:
>
> def f(x):
>    global _
>    _ = []
>
> und dann
>
> def g():
>    l = [a for a, _ in pairs]
>    print _
>
> (ist jetzt frei erfunden, Kontext bitte passend dazudenken)
>
> dann habe ich in g() ein potentiell unerwartetes Ergebnis, nämlich den Wert
> des zweiten Elements des letzten pairs-Elements, nicht etwa die global
> definierte list.
>
> Ganz böse wird es bei
>
> def h():
>    global _
>    l = [a for a, _ in pairs]
>
> weil da das global definierte _ durch etwas ganz anderes ersetzt wird
>
> (zumindest in 2.x).
>
>
>
>> Diese Namen sind in
>> Python gar nicht zulässig. Ein Namenskonflikt ist daher ausgeschlossen.
>
>
> Hä? Wenn ein Objekt, das unter _ angesprochen wird, __getitem__()
> implementiert, ist _[1] doch einwandfrei gültig, wenn auch nicht als
> Bezeichner, sondern als Ausdruck?
>
> Oder verstehe ich Dich grade komplett miß?

Ja, denn es geht um etwas ganz anderes.  Bis Python 2.6 hat der
Interpreter *implizit* die sich noch im Aufbau befindliche Liste
während der Ausführung einer List-Comprehension an den Namen "_[1]"
gebunden.  Derartige Namen sind zwar syntaktisch nicht gültig, doch
die Semantik von Python unterstützt sie durchaus [1].  Man konnte
diese Namen missbrauchen, um auf diese Liste zuzugreifen, und
beispielsweise "[x for x in l if x not in locals()['_[1]']]"
verwenden, um eine duplikatfreie Liste zu erzeugen.

Allerdings waren diese Namen immer Implementierungsdetail, und wurden
in Python 2.7 ohnehin entfernt.

[1] Man kann in Python syntaktisch nicht gültige Namen für Attribute
verwenden, indem man indirekt, beispielsweise über "globals()" oder
über "setattr()" darauf zugreift.  "setattr(some_object, 'foo + bar')"
erzeugt das Attribut "foo + bar" auf "some_object", an das man – da
"foo + bar" syntaktisch nicht gültig ist – allerdings nur über
"getattr()" herankommt.


Mehr Informationen über die Mailingliste python-de