Python: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
(86 dazwischenliegende Versionen von 12 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
[[Kategorie:Sprache]] | [[Kategorie:Sprache]] | ||
= Links = | |||
* [[Jupyter]] | |||
* https://www.python.org/downloads/windows/ | |||
= Exception = | |||
<syntaxhighlight lang="python"> | |||
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() | |||
</syntaxhighlight> | |||
= Regular Expression = | |||
<syntaxhighlight lang="python"> | |||
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) | |||
</syntaxhighlight> | |||
= Datentypen = | = Datentypen = | ||
* | == String == | ||
* "x" und 'x' sind gleichwertig | |||
=== Formatierung === | |||
* 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) | |||
"{0:d} / {0:x}".format(714) | |||
"{}-{}: {}".format('abc.txt', 9, 7.99) | |||
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 (List) == | |||
* 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== | == Dictionary== | ||
< | <syntaxhighlight lang="python"> | ||
x = { 'key' : 'val', 'xyz': 3 } | x = { 'key' : 'val', 'xyz': 3 } | ||
x['key'] = value | x['key'] = value | ||
Zeile 23: | 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 | for key, value in x.items(): | ||
key | print(key, value) | ||
for key in x | for key in x: | ||
print key | print key | ||
</ | </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 35: | Zeile 99: | ||
== Mengen == | == Mengen == | ||
< | <syntaxhighlight lang="python"> | ||
s = | 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 45: | Zeile 116: | ||
isPartOf = s <= f | isPartOf = s <= f | ||
diff = s - f | diff = s - f | ||
</ | </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 == | |||
<syntaxhighlight lang="python"> | |||
isStringOrSubclass = isinstance(aVariable, str) | |||
isString = type(aVariable) is str | |||
isList = type([1, 2]) is list | |||
isDict = type({ 0:"a", 1:"b" }) is dict | |||
</syntaxhighlight> | |||
== Spezielle Methoden/Attribute == | |||
* Statische Methoden: | |||
<syntaxhighlight lang="python"> | |||
class X: | |||
# statische Variable | |||
_data = [] | |||
@staticmethod | |||
def add(item): | |||
X._data.append(item) | |||
X.add("new") | |||
</syntaxhighlight> | |||
* Feststellen, ob Attribut existiert: hasattr(instance, nameOfAttribute) | |||
* dynamischer Code: | |||
<syntaxhighlight lang="python"> | |||
exec 'import ' + module | |||
</syntaxhighlight> | |||
* Vollständige Kopie (deep copy): | |||
<syntaxhighlight lang="python"> | |||
import copy | |||
x = [1, 2] | |||
y = copy.deepcopy(x) | |||
</syntaxhighlight> | |||
* Superclass-Konstruktor: | |||
<syntaxhighlight lang="python"> | |||
class Parent: | |||
def __init__(self, name) | |||
self._name = name | |||
class Child(Parent): | |||
def __init__(self, name): | |||
Parser.__init__(self, name) | |||
</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 = | |||
== 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 == | |||
<syntaxhighlight lang="python"> | |||
with supbprocess.popen([ '/usr/bin/wc', '-l', file ], stdout=subprocess.PIPE) as proc: | |||
count = int(proc.stdout.read().decode()) | |||
</syntaxhighlight> | |||
== Dateien == | == Dateien == | ||
< | * Lesen: | ||
<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() | # fp.close() ist implizit | ||
</ | </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: | |||
<syntaxhighlight lang="python"> | |||
with open(self._filename, "w") as fp, open(self._input, "r") as fpInp: | |||
line = fpInp.read() | |||
fp.write(line); | |||
</syntaxhighlight> | |||
= 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 == | |||
<syntaxhighlight lang="python"> | |||
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) | |||
</syntaxhighlight> | |||
== | == Klasse als Sequenz == | ||
< | 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: | |||
<syntaxhighlight lang="python"> | |||
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__() | |||
</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())