Python: Unterschied zwischen den Versionen

Aus Info-Theke
Zur Navigation springen Zur Suche springen
 
(68 dazwischenliegende Versionen von 9 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
[[Kategorie:Sprache]]
[[Kategorie:Sprache]]
= Links =
* [[Jupyter]]
* https://www.python.org/downloads/windows/
= Exception =
= Exception =
<pre>
<syntaxhighlight lang="python">
try:
try:
   raise Exception("not allowed")
   raise Exception("not allowed")
Zeile 14: Zeile 18:
finally:
finally:
   closeIt()
   closeIt()
</pre>
</syntaxhighlight>


= Regular Expression =
= Regular Expression =
<pre>
<syntaxhighlight lang="python">
rexpr = compile(r"([\da-z]+)")
import re
rexpr = re.compile(r"([\da-z]+)")
match = rexpr.match(line)
match = rexpr.match(line)
if match != None:
if match != None:
   number = (int) rexpr.group(1)
   number = (int) rexpr.group(1)
</pre>
# Replacement:
regex = re.compile(r"A\d+", re.IGNORECASE)
for line in some_file:
    other = regex.sub('<Id>', line)
# Replacement mit Referenzen:
s = 'aaa@xxx.com bbb@yyy.net ccc@zzz.org'
re.sub('([a-z]+)@([a-z]+)', r'\2@\1', s)
</syntaxhighlight>


= Datentypen =
= Datentypen =
== String ==
== String ==
* "x" und 'x' sind gleichwertig
* "x" und 'x' sind gleichwertig
* Formatierung
=== Formatierung ===
<pre>
* f-String
<syntaxhighlight lang="python">
# Gleitpunktzahl mit 3 Stellen ausgeben:
f'{self.floatValue:.3f}'
# 2-stellig mit führender 0 ausgeben:
f'{sec//3600}:{sec%3600//60:02}:{sec%60:02}'
# String linksbündig:
f'{data:<10}'
# String rechtsbündig:
f'{data:>10}'
</syntaxhighlight>
* str.format()
<syntaxhighlight lang="python">
"{:3.7f} {:s} {:07d}".format(3.14, "hello", 100)
"{:3.7f} {:s} {:07d}".format(3.14, "hello", 100)
"{0:d} / {0:x}".format(714)
"{0:d} / {0:x}".format(714)
"{}-{}: {}".format('abc.txt', 9, 7.99)
"{}-{}: {}".format('abc.txt', 9, 7.99)
</pre>
precision=2
'{:.Pf}'.replace('P', str(precision)).format(value)
</syntaxhighlight>
* Bytes -> String: b'data'.decode("utf-8")
* String -> Bytes: "string".encode("utf-8")
* capitalize() count() endswith() find() index()
* isalnum() isalpha() isascii() isdecimal() isidentifier() islower() isnumeric() isprintable() isspace() isupper()
* join() partition() rfind() rindex() rpartition() rsplit() split() splitlines() startswith()
* strip() swapcase() title() translate() upper() zfill()
 
== Bytes ==
<syntaxhighlight lang="python">
text = b"abcde".decode("utf-8")
binary = "abc123".encode("utf-8")
</syntaxhighlight>


== Container ==
== Container (List) ==
* List: ['a', 1]; x[1] = 5; x.insert(0, 'firstItem'); x.remove('a'); ix=x.index('a'); del x[0];
* List: ['a', 1]; x[1] = 5; x.insert(0, 'firstItem'); x.remove('a'); ix=x.index('a'); del x[0];
** x.append(99)
** list1 = list1 + list2
* Tupel: t = ('a', 1); l = list(t)
* Tupel: t = ('a', 1); l = list(t)
* list2 = [x for x in range(3)]
* contains99 = 99 in x


== Dictionary==
== Dictionary==
<pre>
<syntaxhighlight lang="python">
x = { 'key' : 'val', 'xyz': 3 }
x = { 'key' : 'val', 'xyz': 3 }
x['key'] = value
x['key'] = value
Zeile 45: Zeile 87:
contains = 'key' in x and 'key2' not in x
contains = 'key' in x and 'key2' not in x
size = len(x)
size = len(x)
for pair in x.iteritems():
for key, value in x.items():
   key = pair[0]
   print(key, value)
for key in x.iterkeys():
for key in x:
   print key
   print key
</pre>
</syntaxhighlight>
* x.itervalues()
* x.itervalues()
* x.setdefault(key[, value]): setzt Wert nur, wenn noch nicht gesetzt
* x.setdefault(key[, value]): setzt Wert nur, wenn noch nicht gesetzt
Zeile 57: Zeile 99:


== Mengen ==
== Mengen ==
<pre>
<syntaxhighlight lang="python">
s = set(['y', 3]) ; f = frozenset(['y', 3])  
s = {3, 'sjoerd'}
s = {c for c in 'abracadabra' if c not in 'abc'}
assertEquals(s, {'d', 'r'})
iterable = ['y', 3];
s = set(iterable) ;  
f = frozenset(iterable)
s.add(9)
s.remove(9)  
for elem in s:
for elem in s:
   print elem
   print elem
Zeile 67: Zeile 116:
isPartOf = s <= f
isPartOf = s <= f
diff = s - f
diff = s - f
</pre>
</syntaxhighlight>
 
== Datum/Zeit ==
<syntaxhighlight lang="python">
import datetime, time
# ab hour optional:
date1 = datetime.datetime(2019, 4, 1, 22, 44, 12, 123456)
timeX = date1.timestamp() # float, sec since epoc
formatted = date1.strftime('%Y.%m.%dT%H:%M:%S')
now = datetime.datetime.now()
daylySeconds = (now.time().hour*60+now.time().minute)*60+now.time().second
yesterday = datetime.datetime.fromtimestamp(time.time() - 24*3600)
firstOfMonth = date1.replace(day=1)
asStringMicroseconds = date1.strftime('%Y.%m.%dT%H:%M:%S.%f dayOfTheWeek (e.g. "Sun"): %a')
weekNo = date1.strftime('%W')
# returns e.g. '08'
date2 = time.time()
date3 = time.localtime(date2)
date4 = time.strftime('%Y.%m.%d-%H:%M:%S.%f dayOfTheWeek: %w', date3)
dateXStr = time.strftime('%Y.%m.%d-%H:%M:%S.%f dayOfTheWeek: %w', time.localtime(timeX))
# Scannen aus Text:
date5 = datetime.datetime.strptime("30 Nov 00", "%d %b %y")
timeTuple = time.strptime("30 Nov 00", "%d %b %y")
# mktime interpretiert lokale Zeit!
time2 = time.mktime(timeTuple)
#  calendar.timegm()¶ interpretiert GM-Time
time3 = calendar.timegm(timeTuple)
date5 = datetime.datetime.fromtimestamp(time.time() - 86400));
 
# Zeitdifferenz
 
date = date + datetime.timedelta(days=50, seconds=27, microseconds=10, milliseconds=29000, minutes=5, hours=8, weeks=2)
diffSec = (date1 - date2).total_seconds()
diffDays = (date1 - date2).days
</syntaxhighlight>
 
=== Leistungsmessung ===
<syntaxhighlight lang="python">
import timeit
body = '''text = 'abcdefg'
s = list(text)
s[6] = 'W'
''.join(s)
'''
print(timeit.timeit(body, number=1000000))
</syntaxhighlight>
 
== Enum ==
<syntaxhighlight lang="python">
from enum import Enum
class TokenType(Enum):
  digit = 1 ; string = 2 ; id = 3 ; operator = 4
 
x = TokenType.id
for item in TokenType:
  print(item.name)
</syntaxhighlight>


== Typcheck ==
== Typcheck ==
<pre>
<syntaxhighlight lang="python">
isStringOrSubclass = isinstance(aVariable, str)
isStringOrSubclass = isinstance(aVariable, str)
isString = type(aVariable) is str
isString = type(aVariable) is str
isList = type([1, 2]) is list
isList = type([1, 2]) is list
isDict = type({ 0:"a", 1:"b" }) is dict
isDict = type({ 0:"a", 1:"b" }) is dict
</pre>
</syntaxhighlight>


== Spezielle Methoden/Attribute ==
== Spezielle Methoden/Attribute ==
* Statische Methoden:
* Statische Methoden:
<pre>
<syntaxhighlight lang="python">
class X:
class X:
   # statische Variable
   # statische Variable
Zeile 88: Zeile 193:


X.add("new")
X.add("new")
</pre>
</syntaxhighlight>
* Feststellen, ob Attribut existiert: hasattr(instance, nameOfAttribute)
* Feststellen, ob Attribut existiert: hasattr(instance, nameOfAttribute)
* dynamischer Code:
* dynamischer Code:
<pre>
<syntaxhighlight lang="python">
exec 'import ' + module
exec 'import ' + module
</pre>
</syntaxhighlight>
* Vollständige Kopie (deep copy):
* Vollständige Kopie (deep copy):
<pre>
<syntaxhighlight lang="python">
import copy
import copy
x = [1, 2]
x = [1, 2]
y = copy.deepcopy(x)
y = copy.deepcopy(x)
</pre>
</syntaxhighlight>
* Superclass-Konstruktor:
* Superclass-Konstruktor:
<pre>
<syntaxhighlight lang="python">
class Parent:
class Parent:
   def __init__(self, name)
   def __init__(self, name)
Zeile 108: Zeile 213:
   def __init__(self, name):
   def __init__(self, name):
       Parser.__init__(self, name)
       Parser.__init__(self, name)
</pre>
</syntaxhighlight>
 
== Funktionale Programmierung ==
<syntaxhighlight lang="python">
import functools, math
array = [ 1, 9, 7, 5 ]
max = functools.reduce(lambda rc, item: item if item > rc else rc, array, -1E+100)
squares = list(map(lambda x: x*x, array))
squares2 = list(filter(lambda x: int(math.sqrt(x)) == math.sqrt(x), array))
</syntaxhighlight>


= Typische Situationen =
= Typische Situationen =
== Division Integer ==
<syntaxhighlight lang="python">
pairs = count // 2
</syntaxhighlight>
== Objekte kopieren (Shallow/Deep Copy) ==
<syntaxhighlight lang="python">
import copy
a = [1, 2, 3]
b = copy.copy(a)
c = [a, [1, 2, 3]]
d = copy.deepcopy(c)
# Speziell bei Listen (shallow copy):
copied_list = original_list[:]
</syntaxhighlight>
== Sortieren ==
<syntaxhighlight lang="python">
a =["Joe", "Eve", "Bob", "alma", "Adam"]
a.sort()
# sort by a global function:
a.sort(key=str.lower)
# sort by a lambda function which calculates the sorting key:
a.sort(key=lambda x: x[2])
# 2-stufig: nach Länge absteigend, dann alphabetisch:
a.sort(key=lambda x: (-len(x), x))
# comparism function:
def mySort(a, b): return len(a) - len(b)
import functools
a.sort(key=functools.cmp_to_key(mySort))
</syntaxhighlight>
== Externes Programm aufrufen ==
== Externes Programm aufrufen ==
<pre>
<syntaxhighlight lang="python">
with supbprocess.popen([ '/usr/bin/wc', '-l', file ], stdout=subprocess.PIPE) as proc:
with supbprocess.popen([ '/usr/bin/wc', '-l', file ], stdout=subprocess.PIPE) as proc:
   count = int(proc.stdout.read().decode())
   count = int(proc.stdout.read().decode())
</pre>
</syntaxhighlight>


== Dateien ==
== Dateien ==
* Lesen:
* Lesen:
<pre>
<syntaxhighlight lang="python">
with open(self._filename, "r") as fp:
with open(self._filename, "r") as fp:
   for line in fp:
   for line in fp:
     print(line)
     print(line)
   # fp.close() ist implizit
   # fp.close() ist implizit
</pre>
</syntaxhighlight>
* Binärdatei:
<syntaxhighlight lang="python">
with open(self._filename, "rb") as fp:
  data = fp.read(8000)
  while data:
    doIt(data)
    data = fp.read(8000)
</syntaxhighlight>
 
* Schreiben:
* Schreiben:
<pre>
<syntaxhighlight lang="python">
with open(self._filename, "w") as fp:
with open(self._filename, "w") as fp, open(self._input, "r") as fpInp:
   fp.write("Hello\nWorld\n");
  line = fpInp.read()
</pre>
   fp.write(line);
</syntaxhighlight>


= Sprachbesonderheiten =
= Sprachbesonderheiten =
== Variable Zahl Parameter in Methode: Liste ==
<syntaxhighlight lang="python">
# numbers ist eine Liste:
def find_sum(*numbers):
    result = 0
    for num in numbers:
        result = result + num
   
    print("Sum = ", result)
# function call with 3 arguments
find_sum(1, 2, 3)
</syntaxhighlight>
== Variable Zahl Parameter in Methode: Map ==
<syntaxhighlight lang="python">
# numbers ist eine Liste:
def show(**params):
    result = 0
    for name,value in params.items():
        print(f'{name}: {value}')
# function call with 3 arguments
show(jonny="admin", berta="user")
</syntaxhighlight>
== Reflection ==
<syntaxhighlight lang="python">
class A:
  def __init__(self):
    self._a = 0
  def asString(self):
    return 'A'
a = A()
assertTrue(hasattr(a, '_a'));
assertTrue(hasattr(a, 'asString'));
assertFalse(hasattr(a, 'b'));
print(getattr(a, '_a))
names = ['bob', 'alice']
it = iter(names)
assertTrue(next(it) == 'bob')
assertTrue(next(it) == 'alice')
</syntaxhighlight>
== Type Hints ==
<syntaxhighlight lang="python">
from typing import List, Sequence, Mapping
Vector = list[float]
def sqr(x: float) -> float:
  return x*x
def first(items: Sequence[str]) -> str:
  return items[0]
def printName(name: str) -> None:
  print(name);
def evalMap(map: Mapping[int, str]):
  return map[3] == 'Hello'
</syntaxhighlight>
== Aufruf Superclass-Konstruktor ==
<syntaxhighlight lang="python">class B (A):
  def __init__(self, a):
    A.__init__(self, a)
  def asString(self):
    return 'B: ' + super().asString
</syntaxhighlight>
== Abstrakte Klasse ==
<syntaxhighlight lang="python">class A:
@abstractmethod
def process(self):
  pass
</syntaxhighlight>
== Verschachtelte Methoden ==
== Verschachtelte Methoden ==
<pre>
<syntaxhighlight lang="python">
class Example:
class Example:
   def scan(self, file):
   def scan(self, file):
Zeile 148: Zeile 380:
       def _error(msg):
       def _error(msg):
         print("line {}: {}\n{}".format(lineNo, msg, line)
         print("line {}: {}\n{}".format(lineNo, msg, line)
</pre>       
</syntaxhighlight>       
          
          


Zeile 154: Zeile 386:
Damit eine Klasse mit "x in classInstance" angesprochen werden kann, muss es einen Iterator geben.
Damit eine Klasse mit "x in classInstance" angesprochen werden kann, muss es einen Iterator geben.
Im Beispiel wird dies in einer Klasse zusammengefasst:__iter__() liefert als Iterator sich selbst und __next__() implementiert diesen Iterator:
Im Beispiel wird dies in einer Klasse zusammengefasst:__iter__() liefert als Iterator sich selbst und __next__() implementiert diesen Iterator:
<pre>
<syntaxhighlight lang="python">
class Example:
class Example:
   def __init__():
   def __init__():
Zeile 170: Zeile 402:
   def next():
   def next():
     return self.__next__()
     return self.__next__()
</pre>
</syntaxhighlight>
 
== Generator ==
* einfach mindestens ein "yield <value>" in die Funktion einfügen
* Bei Rekursion: yield from <method_call>
<syntaxhighlight lang="python">def nextFile(directory)
for node in os.listdir(directory):
  full = directory + os.sep + node
  yield full
  if os.path.isdir(full):
    yield from nextFile(full)
</syntaxhighlight>
 
== Unittests ==
<syntaxhighlight lang="python">
import unittest
import sim_parser as sim
 
class SimParserTest(unittest.TestCase):
   
    def testNextToken(self):
        parser = sim.SimParser()
        parser.setSource('''10 'abc' var12 +;
    ''')
        self.assertEqual(parser.token(0), sim.Number(10, True, 0, 0))
 
if __name__ == "__main__":
    unittest.main()
</syntaxhighlight>
 
== ArgParse ==
<syntaxhighlight lang="python">
def main(argv=None): # IGNORE:C0111
    '''Command line options.'''
    if argv is None:
        argv = sys.argv
    program_name = os.path.basename(sys.argv[0])
    program_version = "v%s" % __version__
    program_build_date = str(__updated__)
    program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
    program_license = '''%s
  Created by Hamatoma on %s.
  Copyright 2022 Hamatoma. All rights reserved.
 
  Licensed under the Apache License 2.0
  http://www.apache.org/licenses/LICENSE-2.0
 
  Distributed on an "AS IS" basis without warranties
  or conditions of any kind, either express or implied.
USAGE
''' % (program_shortdesc, str(__date__))
    try:
        # Setup argument parser
        parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
        parser.add_argument('file', help="file to dump")
        parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='set verbosity level [default: %(default)s]')
        parser.add_argument('-o', '--offset', dest='offset', help='offset of the output [default: %(default)s]', metavar='OFFSET', type=int, default=0)
        parser.add_argument('-l', '--length', dest='length', help='length of the output [default: %(default)s]', metavar='LENGTH', type=int, default=80 )
        parser.add_argument('-V', '--version', action='version', version=program_version_message)
        args = parser.parse_args(argv[1:])
        offset = args.offset
        length = args.length
        filename = args.file
        if not os.path.exists(filename):
            raise CLIError('not a file: ' + filename)
...
        return 0
    except KeyboardInterrupt:
        return 0
    except Exception as e:
        if DEBUG or TESTRUN:
            raise(e)
        indent = len(program_name) * " "
        sys.stderr.write(program_name + ": " + repr(e) + "\n")
        sys.stderr.write(indent + "  for help use --help")
        return 2
if __name__ == "__main__":
    sys.exit(main())
</syntaxhighlight>

Aktuelle Version vom 16. Oktober 2024, 07:36 Uhr

Links[Bearbeiten]

Exception[Bearbeiten]

try:
   raise Exception("not allowed")
except ValueError as error:
   print('value error: ' + repr(error))
except SyntaxError as error:
   print('syntax error: ' + repr(error))
else:
    raise Exception("unknown")
try:
   doit()
finally:
   closeIt()

Regular Expression[Bearbeiten]

import re
rexpr = re.compile(r"([\da-z]+)")
match = rexpr.match(line)
if match != None:
   number = (int) rexpr.group(1)
# Replacement:
regex = re.compile(r"A\d+", re.IGNORECASE)
for line in some_file:
    other = regex.sub('<Id>', line)
# Replacement mit Referenzen:
s = 'aaa@xxx.com bbb@yyy.net ccc@zzz.org'
re.sub('([a-z]+)@([a-z]+)', r'\2@\1', s)

Datentypen[Bearbeiten]

String[Bearbeiten]

  • "x" und 'x' sind gleichwertig

Formatierung[Bearbeiten]

  • f-String
# Gleitpunktzahl mit 3 Stellen ausgeben:
f'{self.floatValue:.3f}'
# 2-stellig mit führender 0 ausgeben:
f'{sec//3600}:{sec%3600//60:02}:{sec%60:02}'
# String linksbündig:
f'{data:<10}'
# String rechtsbündig:
f'{data:>10}'
  • str.format()
"{:3.7f} {:s} {:07d}".format(3.14, "hello", 100)
"{0:d} / {0:x}".format(714)
"{}-{}: {}".format('abc.txt', 9, 7.99)
precision=2
'{:.Pf}'.replace('P', str(precision)).format(value)
  • Bytes -> String: b'data'.decode("utf-8")
  • String -> Bytes: "string".encode("utf-8")
  • capitalize() count() endswith() find() index()
  • isalnum() isalpha() isascii() isdecimal() isidentifier() islower() isnumeric() isprintable() isspace() isupper()
  • join() partition() rfind() rindex() rpartition() rsplit() split() splitlines() startswith()
  • strip() swapcase() title() translate() upper() zfill()

Bytes[Bearbeiten]

text = b"abcde".decode("utf-8") 
binary = "abc123".encode("utf-8")

Container (List)[Bearbeiten]

  • List: ['a', 1]; x[1] = 5; x.insert(0, 'firstItem'); x.remove('a'); ix=x.index('a'); del x[0];
    • x.append(99)
    • list1 = list1 + list2
  • Tupel: t = ('a', 1); l = list(t)
  • list2 = [x for x in range(3)]
  • contains99 = 99 in x

Dictionary[Bearbeiten]

x = { 'key' : 'val', 'xyz': 3 }
x['key'] = value
del x['key'];
contains = 'key' in x and 'key2' not in x
size = len(x)
for key, value in x.items():
  print(key, value)
for key in x:
  print key
  • x.itervalues()
  • x.setdefault(key[, value]): setzt Wert nur, wenn noch nicht gesetzt
  • x.keys(), x.values()
  • x.copy(): flache Kopie
  • x.update(dict): addiert dict zu x

Mengen[Bearbeiten]

s = {3, 'sjoerd'}
s = {c for c in 'abracadabra' if c not in 'abc'}
assertEquals(s, {'d', 'r'})
iterable = ['y', 3];
s = set(iterable) ; 
f = frozenset(iterable)
s.add(9)
s.remove(9) 
for elem in s:
  print elem
size = len(s)
contains = 3 in s and 4 not in s
intersection = s & f
union = s | f
isPartOf = s <= f
diff = s - f

Datum/Zeit[Bearbeiten]

import datetime, time
# ab hour optional:
date1 = datetime.datetime(2019, 4, 1, 22, 44, 12, 123456)
timeX = date1.timestamp() # float, sec since epoc
formatted = date1.strftime('%Y.%m.%dT%H:%M:%S')
now = datetime.datetime.now()
daylySeconds = (now.time().hour*60+now.time().minute)*60+now.time().second
yesterday = datetime.datetime.fromtimestamp(time.time() - 24*3600)
firstOfMonth = date1.replace(day=1)
asStringMicroseconds = date1.strftime('%Y.%m.%dT%H:%M:%S.%f dayOfTheWeek (e.g. "Sun"): %a')
weekNo = date1.strftime('%W')
# returns e.g. '08'
date2 = time.time()
date3 = time.localtime(date2)
date4 = time.strftime('%Y.%m.%d-%H:%M:%S.%f dayOfTheWeek: %w', date3)
dateXStr = time.strftime('%Y.%m.%d-%H:%M:%S.%f dayOfTheWeek: %w', time.localtime(timeX))
# Scannen aus Text:
date5 = datetime.datetime.strptime("30 Nov 00", "%d %b %y")
timeTuple = time.strptime("30 Nov 00", "%d %b %y")
# mktime interpretiert lokale Zeit!
time2 = time.mktime(timeTuple)
#  calendar.timegm()¶ interpretiert GM-Time
time3 = calendar.timegm(timeTuple)
date5 = datetime.datetime.fromtimestamp(time.time() - 86400));

# Zeitdifferenz 

date = date + datetime.timedelta(days=50, seconds=27, microseconds=10, milliseconds=29000, minutes=5, hours=8, weeks=2)
diffSec = (date1 - date2).total_seconds()
diffDays = (date1 - date2).days

Leistungsmessung[Bearbeiten]

import timeit
body = '''text = 'abcdefg'
s = list(text)
s[6] = 'W'
''.join(s)
'''
print(timeit.timeit(body, number=1000000))

Enum[Bearbeiten]

from enum import Enum
class TokenType(Enum):
  digit = 1 ; string = 2 ; id = 3 ; operator = 4

x = TokenType.id
for item in TokenType:
  print(item.name)

Typcheck[Bearbeiten]

isStringOrSubclass = isinstance(aVariable, str)
isString = type(aVariable) is str
isList = type([1, 2]) is list
isDict = type({ 0:"a", 1:"b" }) is dict

Spezielle Methoden/Attribute[Bearbeiten]

  • Statische Methoden:
class X:
   # statische Variable
   _data = []
   @staticmethod
   def add(item):
      X._data.append(item)

X.add("new")
  • Feststellen, ob Attribut existiert: hasattr(instance, nameOfAttribute)
  • dynamischer Code:
exec 'import ' + module
  • Vollständige Kopie (deep copy):
import copy
x = [1, 2]
y = copy.deepcopy(x)
  • Superclass-Konstruktor:
class Parent:
   def __init__(self, name)
      self._name = name
class Child(Parent):
   def __init__(self, name):
      Parser.__init__(self, name)

Funktionale Programmierung[Bearbeiten]

import functools, math
array = [ 1, 9, 7, 5 ]
max = functools.reduce(lambda rc, item: item if item > rc else rc, array, -1E+100)
squares = list(map(lambda x: x*x, array))
squares2 = list(filter(lambda x: int(math.sqrt(x)) == math.sqrt(x), array))

Typische Situationen[Bearbeiten]

Division Integer[Bearbeiten]

pairs = count // 2


Objekte kopieren (Shallow/Deep Copy)[Bearbeiten]

import copy
a = [1, 2, 3]
b = copy.copy(a)
c = [a, [1, 2, 3]]
d = copy.deepcopy(c)
# Speziell bei Listen (shallow copy):
copied_list = original_list[:]


Sortieren[Bearbeiten]

a =["Joe", "Eve", "Bob", "alma", "Adam"]
a.sort()
# sort by a global function:
a.sort(key=str.lower)
# sort by a lambda function which calculates the sorting key:
a.sort(key=lambda x: x[2])
# 2-stufig: nach Länge absteigend, dann alphabetisch:
a.sort(key=lambda x: (-len(x), x))
# comparism function:
def mySort(a, b): return len(a) - len(b)
import functools
a.sort(key=functools.cmp_to_key(mySort))

Externes Programm aufrufen[Bearbeiten]

with supbprocess.popen([ '/usr/bin/wc', '-l', file ], stdout=subprocess.PIPE) as proc:
   count = int(proc.stdout.read().decode())

Dateien[Bearbeiten]

  • Lesen:
with open(self._filename, "r") as fp:
  for line in fp:
     print(line)
  # fp.close() ist implizit
  • Binärdatei:
with open(self._filename, "rb") as fp:
  data = fp.read(8000)
  while data:
     doIt(data)
     data = fp.read(8000)
  • Schreiben:
with open(self._filename, "w") as fp, open(self._input, "r") as fpInp:
  line = fpInp.read()
  fp.write(line);

Sprachbesonderheiten[Bearbeiten]

Variable Zahl Parameter in Methode: Liste[Bearbeiten]

# numbers ist eine Liste:
def find_sum(*numbers):
    result = 0
    for num in numbers:
        result = result + num
    
    print("Sum = ", result)

# function call with 3 arguments
find_sum(1, 2, 3)

Variable Zahl Parameter in Methode: Map[Bearbeiten]

# numbers ist eine Liste:
def show(**params):
    result = 0
    for name,value in params.items():
        print(f'{name}: {value}')

# function call with 3 arguments
show(jonny="admin", berta="user")

Reflection[Bearbeiten]

class A:
  def __init__(self):
    self._a = 0
  def asString(self):
    return 'A'
a = A()
assertTrue(hasattr(a, '_a'));
assertTrue(hasattr(a, 'asString'));
assertFalse(hasattr(a, 'b'));
print(getattr(a, '_a))
names = ['bob', 'alice']
it = iter(names)
assertTrue(next(it) == 'bob')
assertTrue(next(it) == 'alice')

Type Hints[Bearbeiten]

from typing import List, Sequence, Mapping
Vector = list[float]
def sqr(x: float) -> float:
  return x*x
def first(items: Sequence[str]) -> str:
  return items[0]
def printName(name: str) -> None:
  print(name);
def evalMap(map: Mapping[int, str]):
  return map[3] == 'Hello'

Aufruf Superclass-Konstruktor[Bearbeiten]

class B (A):
  def __init__(self, a):
    A.__init__(self, a)
  def asString(self):
    return 'B: ' + super().asString

Abstrakte Klasse[Bearbeiten]

class A:

@abstractmethod
def process(self):
  pass

Verschachtelte Methoden[Bearbeiten]

class Example:
  def scan(self, file):
     lineNo = 0
     for line in file:
       lineNo += 1
       if line.startswith('[':
           chapter = Chapter(line[1:-1])
       elif re.match(r'\w+='):
           var, value = line.split('=')
           chapter._vars[var] = value
       else:
           _error('invalid input')
      def _error(msg):
         print("line {}: {}\n{}".format(lineNo, msg, line)


Klasse als Sequenz[Bearbeiten]

Damit eine Klasse mit "x in classInstance" angesprochen werden kann, muss es einen Iterator geben. Im Beispiel wird dies in einer Klasse zusammengefasst:__iter__() liefert als Iterator sich selbst und __next__() implementiert diesen Iterator:

class Example:
  def __init__():
    self._nextItems = []
  def __iter__():
    self._nextItems = [1, 2, 3]
    return self
  def __next__():
    if len(self._nextItem) == 0:
      raise StopIteration
    else:
      rc = self._nextItems[0]
      del self._nextItems[0]
      return rc
  def next():
    return self.__next__()

Generator[Bearbeiten]

  • einfach mindestens ein "yield <value>" in die Funktion einfügen
  • Bei Rekursion: yield from <method_call>
def nextFile(directory)
 for node in os.listdir(directory):
  full = directory + os.sep + node
  yield full
  if os.path.isdir(full):
    yield from nextFile(full)

Unittests[Bearbeiten]

import unittest
import sim_parser as sim

class SimParserTest(unittest.TestCase):
    
    def testNextToken(self):
        parser = sim.SimParser()
        parser.setSource('''10 'abc' var12 +;
    ''')
        self.assertEqual(parser.token(0), sim.Number(10, True, 0, 0))

if __name__ == "__main__": 
    unittest.main()

ArgParse[Bearbeiten]

def main(argv=None): # IGNORE:C0111
    '''Command line options.'''
    if argv is None:
        argv = sys.argv
    program_name = os.path.basename(sys.argv[0])
    program_version = "v%s" % __version__
    program_build_date = str(__updated__)
    program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
    program_license = '''%s
  Created by Hamatoma on %s.
  Copyright 2022 Hamatoma. All rights reserved.

  Licensed under the Apache License 2.0
  http://www.apache.org/licenses/LICENSE-2.0

  Distributed on an "AS IS" basis without warranties
  or conditions of any kind, either express or implied.
USAGE
''' % (program_shortdesc, str(__date__))
    try:
        # Setup argument parser
        parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
        parser.add_argument('file', help="file to dump")
        parser.add_argument('-v', '--verbose', dest='verbose', action='count', help='set verbosity level [default: %(default)s]')
        parser.add_argument('-o', '--offset', dest='offset', help='offset of the output [default: %(default)s]', metavar='OFFSET', type=int, default=0)
        parser.add_argument('-l', '--length', dest='length', help='length of the output [default: %(default)s]', metavar='LENGTH', type=int, default=80 )
        parser.add_argument('-V', '--version', action='version', version=program_version_message)
        args = parser.parse_args(argv[1:])
        offset = args.offset
        length = args.length
        filename = args.file
        if not os.path.exists(filename):
            raise CLIError('not a file: ' + filename)
...
        return 0
    except KeyboardInterrupt:
        return 0
    except Exception as e:
        if DEBUG or TESTRUN:
            raise(e)
        indent = len(program_name) * " "
        sys.stderr.write(program_name + ": " + repr(e) + "\n")
        sys.stderr.write(indent + "  for help use --help")
        return 2
if __name__ == "__main__":
    sys.exit(main())