Re: [Python-de] Wie sieht Python fuer mich aus?
Hi Stefan, On 2017-01-08 18:52, Stefan Ram wrote:
Ausgeben
»print« rundet Zahlen bei der Ausgabe etwas, während die Konsole alle Nachkommastellen anzeigt.
`print` verwendet die Methode `__str__` zur Umwandlung in einen String, während in der Konsole (Python-Shell) `__repr__` verwendet wird. Beide Methoden können unterschiedlich implementiert sein (siehe unten).
Variablen
Eine Variable wird durch eine Zuweisung definiert. Eine Variable hat keinen Typ, sondern Werte haben einen Typ.
Eine wichtige Einsicht!
Eine Variable wird an eine Liste gebunden, die Liste wird also bei einer Zuweisung nicht kopiert. (Kopieren kann mit nachgestelltem slice »[:]« erfolgen.)
Das kopiert nur die erste "Ebene" der Liste ("flache Kopie", "shallow copy"). "Innere" Listen oder Objekte werden dabei also nicht kopiert, sondern deren Referenzen übernommen.
L = [[1, 2], [3, 4]] L2 = L[:] L[0].append(2) L2 [[1, 2, 2], [3, 4]]
»range(2,7)« ergibt einen Bereich (einen Iterator) und »range(2)« bedeutet »range(0,2)«.
In Python 2 ergibt `range` eine Liste, in Python 3 einen Iterator.
Die spezielle Methode »__string__« repräsentiert Objekte einer Klasse als Zeichenfolge.
Muster
def __string__(self,...): return "string"
Du meintest wahrscheinlich `__str__`. Wie oben gesagt, gibt es auch noch `__repr__`. Üblicherweise wird `__str__` für eine "nutzerfreundliche" Darstellung verwendet und `__repr__` eher für eine "entwicklerfreundliche".
s = "abc " print(s) abc s # Nur hier sieht man das Leerzeichen am Ende 'abc '
import decimal d = decimal.Decimal("1.23") print(d) 1.23 d Decimal('1.23')
Zu deinem Beispiel: "Technisch" kann man `__str__` und `__repr__` mit weiteren Argumenten außer `self` definieren, aber es wird praktisch nie gemacht: Beide Methoden werden üblicherweise in Zusammenhängen verwendet, bei denen keine Argumente übergeben werden (können).
class A: ... def __str__(self, x="x"): ... return "a" + x ... a = A() print(a) ax print(a.__str__("y")) ay
Wie du siehst, ist der explizite Aufruf von `__str__` relativ "unhandlich". :-) Viele Grüße Stefan
[Zweiter Versuch mit ausgelagertem Anhang, siehe http://imgur.com/a/5iA5m] On 09 Jan 2017, at 06:23, Stefan Schwarzer <sschwarzer@sschwarzer.net> wrote:
Variablen
Eine Variable wird durch eine Zuweisung definiert. Eine Variable hat keinen Typ, sondern Werte haben einen Typ.
Eine wichtige Einsicht!
Wobei der Begriff “Variable” leider häufig sehr vage verwendet wird. Es wird einiges klarer, wenn man andere Begriffe benutzt (und auch die jeweilige Rolle mit in Betracht zieht). In der Ausbildung spricht man eher von “Bezeichnern” bzw. “Identifier”. Das macht klarer, dass eine “Variable” letztlich auch nur eine Art Tupel ist, das aus einem Namen und einem Wert besteht. Und, richtig, eine Typ-Information hat nur für die Werte irgendeinen Sinn.
Eine Variable wird an eine Liste gebunden, die Liste wird
also bei einer Zuweisung nicht kopiert. (Kopieren kann mit nachgestelltem slice »[:]« erfolgen.)
Das kopiert nur die erste "Ebene" der Liste ("flache Kopie", "shallow copy"). "Innere" Listen oder Objekte werden dabei also nicht kopiert, sondern deren Referenzen übernommen.
Ich habe unten mal ein super-uralt-unsupported-Tool von mir bemüht (hoffe, das Bild kommt über die Liste; alle rechteckigen Objekte haben eine eigene ID). Gruß, Dinu .. code-block:: python # https://pypi.python.org/pypi/sh import sh # https://pypi.python.org/pypi/pyrels from pyrels import pyrels2dot L = [1, 2, [3, [4, 5]]] pyrels2dot.namespace2dot({'L': L}, "list.dot") sh.dot('-Tpng', 'list.dot', _out='list.png') Lc = L[:] pyrels2dot.namespace2dot({'Lc': Lc, 'L': L}, "list_copy.dot") sh.dot('-Tpng', 'list_copy.dot', _out='list_copy.png’) # Bild list_copy.png siehe anbei # oder hier: http://imgur.com/a/5iA5m
Am 09.01.17 um 06:23 schrieb Stefan Schwarzer:
»range(2,7)« ergibt einen Bereich (einen Iterator) und »range(2)« bedeutet »range(0,2)«.
In Python 2 ergibt `range` eine Liste, in Python 3 einen Iterator.
Hier geht es etwas genauer. ;) `range` in Python 3 gibt keinen Iterator sonder ein `range`-Objekt zurück:
type(range(10)) range
Wichtige Unterschiede: * `range` unterstützt kein `next`:
next(range(10)) TypeError: 'range' object is not an iterator
* `range`-Objekte lassen sich indizieren
r = range(10) r[0] 0 Iteratoren nicht: i = iter('abc') i[0] TypeError: 'str_iterator' object is not subscriptable
* `range`-Objekte lassen sich immer wieder in Listen (oder andere Sequenzen) umwandeln:
r = range(10) list(r) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] list(r) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Itertoren sind dagegen "einmalig": i = iter('abc') list(i) ['a', 'b', 'c'] list(i) []
Bei einer (typischen) Nutzung in einer `for`-Schleife:
for x in range(10):
gibt es allerdings keine Unterschiede. Mike
participants (3)
-
Dinu Gherman -
Mike Müller -
Stefan Schwarzer