Skip to main content

Basis-Syntax von Python und Beispiele

Python hat Ähnlichkeiten mit den Sprachen der „C-Familie“, aber es gibt auch einige signifikante Unterschiede und eindeutige Eigenschaften.

Der deutlichste syntaktische Unterschied von Python zu Sprachen wie C oder ST ist, dass der Python-Parser Blockstrukturen an ihrer Einrückung erkennt. Es gibt kein BEGIN/END oder geschweifte Klammern {} um die Bodys von IF/ELSE-Bedingungen, FOR- und WHILE-Schleifen oder Funktionen zu kennzeichnen.

Kommentare starten mit # und reichen bis zum Ende der Zeile. In der ersten oder zweiten Zeile des Quellcodes können Sie einen speziellen kennzeichnenden Marker setzen, um die Encodierung der Datei zu deklarieren. Wir empfehlen, UTF-8 als Encodierung zu verwenden, wenn nicht-ASCII-Zeichen benötigt werden.

Einfache Ausgaben zu Debugging-Zwecken erzielen Sie mit print. Mit dem %-Operator erreichen Sie eine ähnliche Funktionalität wie mit der C-Funktion printf(). Die Ausgabe wird in CODESYS im Meldungsfenster angezeigt.

Beispiel 4. Beispiel print
# encoding:utf-8

# defining a function with the parameter i
def do_something(i):
    # if branch
    if i>0:
        print("The value is: %i" % i)
                                                                sum += i
        print("The new sum is: %i" % sum)

    # else if (optional, there can be none or several elif branches)
    elif i=0:
        print("The sum did not change: %i" % sum)

    # and the final else branch (also optional).
    else:
        handle_error()

# an endless while loop
while True:
    print("I got stuck forever!")


Alles, was zum gleichen Block gehört, muss gleich weit eingerückt sein. Die Größe der Einrückung ist egal. Elemente wie runde und geschweifte Klammern haben Vorrang vor Einrückungen. Somit ist der folgende Codeabschnitt völlig korrekt, auch wenn es „schlechter Programmierstil“ ist:

Beispiel 5. Beispiel Einrückung
# warning: bad style below. Kids, don't try this at home!
if foo >= bar:
               print("foobar")
else:
    print(
          "barfoo"
)


Um Uneindeutigkeiten zu vermeiden, sollten Sie innerhalb einer Datei Tabs und Leerzeichen nicht mischen.

Tipp

Das Mischen von Tabs und Leerzeichen gilt in Python 3 aktuell als syntaktischer Fehler.

Der offizielle Python Style Guide empfiehlt Einrückung um 4 Leerzeichen und enthält einige Beispiele von gutem und schlechtem Stil. Eine Kurzfassung zum Kodierstil finden Sie im Python Tutorial.

Ähnlich wie in C und im Gegensatz zu ST, ist Python „case-sensitive“. Schlüsselwörter wie def, if, else oder while müssen klein geschrieben werden (im Gegensatz zur ST-Regel, Schlüsselwörter in Großbuchstaben zu schreiben). Zwei Bezeichner wie „i“ und „I“ bezeichnen auch zwei verschiedene Variablen.

Die folgenden Worte sind in Python reservierte Schlüsselwörter und dürfen nicht als Bezeichner für Variablen, Funktionen etc. verwendet werden: and | as | assert | break | class | continue | def | del | elif | else | except | exec | finally | for | from | global | if | import | in | is | lambda | not | or | pass | print | raise | return | try | while | with | yield.

Python 3 definiert vier weitere Schlüsselwörter: False | None | True | nonlocal. Während das letzte davon wirklich neu ist, waren die ersten drei bereits vordefinierte Konstanten in Python 2 und sollten auf keinen Fall für andere Zwecke verwendet werden.

Für weitere Informationen siehe: Python Style Guide und Python Tutorial

Variablen und Datentypen

Python ist eine stark, aber dynamisch typisierte Sprache - alle Typinformationen werden zur Laufzeit ausgewertet. Variablen halten Referenzen auf Objekte, und das Objekt (nicht die Variable) kennt seinen Typ. Wenn der Programmierer versucht, eine Operation auszuführen, die nicht möglich ist (beispielsweise.eine Addition von Integer und String), erzeugt Python zur Laufzeit eine Exception.

Konsequenterweise gibt es keine Deklarationen für Variablen und ihre Typen. Variablen werden in Python nur dadurch angelegt, dass man ihnen einen Wert zuweist. Dies ist völlig anders als in C und ST, wo stark und statisch typisiert wird. Jede Variable ist mit einem Typ deklariert und der Compiler prüft zur Kompilierungszeit, ob Typ und Operationen zulässig sind.

Sehen Sie im Folgenden einige Beispiele für den Umgang mit Variablen:

Beispiel 6. Beispiel Variablen
# assign the integer 1 to the variable i (also "creates" the variable")
i = 1

# assign the string "foobar" to the variable s
s = "foobar"

# Add 5 to the integer i - this is equivalent to i = i + 5
i += 5
# i now holds the integer 6.

# Try to add i and s - this will throw an exception when executed
# TypeError: unsupported operand type(s) for +: 'int' and 'str'
result = i + s

# variables can also be "undeclared" by deleting them.
# Further access to the variable i will throw a NameError exception,
# as the variable does not exist any more.
del i

i += 5 # now throws an exception: NameError: name 'i' is not defined


Alle bestehenden Variablen referenzieren immer einen Wert. Es gibt keine nicht zugewiesenen oder nicht-initialisierten Variablen in Python. Um die Abwesenheit eines Wertes auszudrücken, wozu man in C oder ST einen Null-Pointer verwenden würde, gibt es in Python ein spezielles Objekt namens None. Sein einziger Zweck ist auszudrücken „hier gibt es keinen Wert“, obwohl tatsächlich None eine existierende Instanz der Klasse NoneType ist.

NumerischeTypen und Gleitkommatypen

Im Unterschied zu den Dutzenden von Ganzzahltypen in IEC oder C gibt es nur einen einzigen Ganzzahltypen in Python. Ganzzahltypen in Python haben keine feste Größe, sondern wachsen nach Bedarf und sind nur durch den verfügbaren Speicherumfang begrenzt.

Beispiel 7. Beispiel Integers.py
from __future__ import print_function

i = 1
print(i)

j = 0x1234   # hex number, is 16#1234 in IEC and 4660 in decimal
k = 0o123    # octal number, is 8#123 in IEC and 83 decimal
l = 0b101010 # binary number, is 2#101010 in IEC and 42 in decimal
print(j, k, l)

m = (2 + 3)*10 # k is 50 now
print(m)

n = 10 ** 100 # 10 to the power of 100
print(n)

Resultierende Ausgabe:

_cds_script_messages_integers.png


Es gibt auch nur einen einzigen Gleitkommazahltypen in Python, der dem IEC-Datentypen LREAL ähnlich ist. Er stellt 64-Bit IEEE-Gleitkommazahlarithmetik bereit.

Die Syntax ist weitgehend wie bei den C-verwandten Sprachen:

Beispiel 8. Beispiele Gleitkommazahltypen
# A simple float...
a = 123.456

# A float containing the integral value 2
b = 2.

# Leading zeroes can be left off
c = .3 # same as 0.3

# Exponential / scientific representation
d = -123e-5


Zwei Spezialfälle sind True und False, zwei Konstanten, die die Booleschen Wahrheitswerte definieren. Sie verhalten sich ähnlich zu den Ganzzahlwerten 0 und 1, außer wenn sie in Strings umgewandelt werden und dann ihren Namen wiedergeben.

Beispiel 9. Beispiel Booleans.py
# booleans behave like integers, except when converted to strings.
# The built-in function "type" can be used to query the type of a value.
print("True:  ", True, type(True))
print("False: ", False, type(False))
print("1:     ", 1, type(1))
print("False + 0: ", False + 0, type(False + 0))
print("True * 5: ", True * 5, type(True * 5))

Resultierende Ausgabe:

_cds_script_messages_booleans.png


Strings

Strings sind in IronPython immer in Unicode und von beliebiger Länge. Es macht keinen Unterschied, ob sie von einem ' oder " eingefaßt sind. Strings können auch dreifache Hochkommas """ oder ''' haben, was mehrzeilige String-Literale ermöglicht.

Ähnlich zu C können spezielle Zeichen mit Hilfe von Backslash-Zeichen ausgenommen werden. Zum Vergleich: In IEC wird für diesen Zweck das Zeichen $ verwendet.

Es gibt auch sogenannte Rohstrings, die andere Regeln für das Backslash-Zeichen haben, welche praktisch sind, wenn der String literale Backslashes enthalten soll. Beispiel: Windows-Dateipfade oder reguläre Ausdrücke..

Beispiel 10. Beispiel Strings.py
# encoding:utf-8
from __future__ import print_function

a = "a simple string"
b = 'another string'
c = "strings may contain 'quotes' of the other type."
d = "multiple string literals" ' are concatenated ' '''by the parser'''
e = "Escaping: quotes: \" \' backslash: \\ newline: \r\n ascii code: \x40"
f = """triple-quoted strings may contain newlines, "single"
'quotes' and '''multiquotes''' of the other type"""
g = "Üňíçǿđȩ is also possible: 北京, Москва, Αθήνα, القاهرة"
h = r"c:\raw\strings\retain\backslashes.txt"

# we iterate over a sequence of all the variables defined above:
for i in (a,b,c,d,e,f,g,h):
    print(i) # prints the contents of the variable

Resultierende Ausgabe:

_cds_script_messages_strings.png


Python hat keinen Typen für Zeichen. Zeichen werden durch die Verwendung von Strings mit Länge 1 ausgedrückt. Somit liefert das Iterieren über einen String, oder das Indizieren in einen String einen Einzelzeichen-String zurück.

Listen und Tupel (Datensätze)

Listen und Tuples entsprechen grob den Arrays in C und IEC, aber es gibt einige auffallende Unterschiede:

  • Der Indexzugriff wird immer überprüft. Wenn auf eine Liste oder ein Tupel mit einem ungültigen Index zugegriffen wird, wird eine Exception ausgegeben.

  • Sowohl Listen als auch Tupel können Elemente verschiedenen Typs (auch anderer Listen und Tupel) enthalten. Dagegen dürfen Arrays in C und IEC nur Elemente eines einzigen Typs enthalten.

  • Listen sind dynamisch, Elemente dürfen jederzeit hinzugefügt, entfernt und ersetzt werden.

  • Tuples sind nicht veränderbar, einmal erzeugt, darf ein Tupel nicht mehr modifiziert werden.

Listen werden mit dem list()-Konstruktor erzeugt. Alternativ kann man eckige Klammern [] verwenden. Tuples werden mit dem tuple()-Konstruktor oder runden Klammern () erzeugt.

Beispiel 11. Beispiel list_tuples.py
from __future__ import print_function
print("Testing tuples and lists")

# We define a tuple with the numbers from 1 to 10:
t = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
print("Tuple:", t)

# We can access the 6th element of the tuple.
# As in C, index counting starts with 0.
print("Element 5:", t[5])

# Subscription is more powerful using the range syntax:
print("Range[2:5]:", t[2:5]) # lower bound is inclusive, upper bound is exclusive.
print("Range[2::2]:", t[2::2]) # start with 3rd element, and print every 2nd element.
print("Range[-3:-1]:", t[-3:-1]) # Start with the 3rd last element, end just before the last element (upper bound is exclusive)
print("Range[::-1]:", t[::-1]) # negative step with - print backwards

# lists are similar to tuples...
l = [11, 12, 13, "8", t] # contains mixed types: 3 integers, a string, and the tuple defined above.
print("List:", l)

# ... but elements can be added or removed dynamically.
l.append(9) # Add a 9 to the list.
print("List with 9:", l)
print("List Range[3:6:2]:", l[3:6:2]) # print the 4th and 6th element.

del l[1] # remove the element at index 1, the 12.
print("Removed[1]:", l)
del l[1:3] # Remove the elements at index 1 and 2, the 13 and the '8'.
print("Removed[1:3]:", l)

Resultierende Ausgabe:

_cds_script_messages_list_tuples.png


Dictionary

Python hat auch einen Hashtable-Typen (aka hashmap). Im Unterschied zur Liste kann er mit beliebigen Elementen indiziert werden, beispielsweise Strings. Sein Konstruktor ist dict() und seine Literale werden mit Hilfe von geschweiften Klammern {} deklariert.

Das Beispielskript dictionaries.py erzeugt die unten gezeigten Ausgabe. In der letzten Zeile wird das Skript mit einer „KeyError“-Exception abbrechen:

Beispiel 12. Beispiel dictionaries.py
from __future__ import print_function
print("Testing dictionaries")

# Declare a dictionary with three entries, the third being a list
d = {1: "a", 2: "b", "my list": [1, 2, 3]}
print(d)

# print the value of the key 1
print(d[1])

# remove the value with the key "my list"
del d["my list"]

# Add a value 4 with the key 3
d[3] = 4
print(d)

# The "get" method returns the second argument if the key cannot be found.
print(d.get(1, 42))
print(d.get(23, 42))

# print all keys in the dictionary
for key in d:
    print(key)

# index access for unknown keys will throw a "KeyError" exception!
print(d[23])

Resultierende Ausgabe:

_cds_script_messages_dictionaries.png

Und nun, in der letzten Zeile bricht das Skript ab:

_cds_script_dictionaries_keyerror.png

Über die Schaltfläche Details erhalten Sie den Stack-Trace. Daraus erfahren Sie die Zeilennummer 27 und den unbekannten Schlüssel 23.

_cds_script_dictionaries_keyerror_details.png