Python

Eine Snippet-Sammlung für Python.

Tricks

In interaktiven Modus wechseln:

import code

code.interact(local=locals())

Strings

Siehe: Strings formatieren - Viele Beispiele zum Formatieren von Strings

# f-Strings (Python 3)
f'Bla {testVar}'

# Substrings
'abcdef'[2:]    # 'cdef'
'abcdef'[:2]    # 'ab'
'abcdef'[:-2]   # 'abcd'
'abcdef'[-2:]   # 'ef'
'abcdef'[2:-2]  # 'cd'

'hello {}'.format('you')          # 'hello you'
'{} {:.1f}'.format(1.567, 1.567)  # '1.567 1.6'
'{:>2}:{:0>2}'.format(2, 3)       # ' 2:03'
'{lat}, {lon}'.format(lat='37.24', lon='-115.81')  # '37.24, -115.81'
'-' * 5                           # '-----'

'  bla '.strip()                  # 'bla'  (trim)

'abc/def'.find('/')  # 3
'abc/def'.find('_')  # -1

'abba'.replace('b', 'c')  # 'acca'

import re
re.sub(r'^(a*)', '\\1\\1', 'abca')  # 'aabca'

int('12')  # 12
float('12.3')  # 12.3

multiline = """
This is a
multiline
string
"""

Umwandlung String <-> Bytes (Python 3):

# Python 3
myBytes = bytearray(myString, 'utf-8')
myString = str(myBytes, 'utf-8')

Datenstrukturen

Siehe Datenstrukturen im Python-Tutorial (Python 2)

Listen (Arrays):

myList = []  # Alternativ: list()
myList.append('foo')
myList.extend([ 'foo', 'bar' ])
len(myList)  # 1

del record[-1]  # Remove last item

for item in myList:
    ...

for index in range(len(myList)):
    ...

for index, item in enumerate(myList):
    ...

if item in myList:
    ...

if item not in myList:
    ...

items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items))

Dictionaries (Hash-Maps):

myDict = {}  # Alternativ: dict()
myDict = { 'key1': 'value', 'key2': 42 }

item = myDict['myKey']      # Raises error if key is not in dict
item = myDict.get('myKey')  # Returns None if key is not in dict

del myDict['myKey']

if 'key1' in dict.keys():
    ...

for key in myDict:
    ...

# Python 2
for key, value in myDict.iteritems():
    ...

# Python 3
for key, value in myDict.items():
    ...

Sets:

mySet = set()
mySet.add('a')

Regex

Siehe Python-Doku zu re

TODO re.search (Siehe Doku search vs match)

import re

match = re.match(regex, content)
if match:
    match.group(1)

# Mit vorherigem Compilieren
myRe = re.compile('^abc$')
match = myRe.match(content)
if match:
    match.group(1)

# Iterieren
for match in re.finditer(r'^bla-([^-]+)$', content, flags=re.MULTILINE):
    match.group(1)

Dateien

Verzeichnis des Skriptes herausfinden:

basePath = os.path.realpath(os.path.dirname(sys.argv[0]))

Pfade zerlegen:

os.path.split('path/to/myfile.ext')       # ('path/to', 'myfile.ext')
os.path.splitext('path/to/myfile.ext')    # ('path/to/myfile', '.ext')

Datei zeilenweise lesen:

with open('myfile') as f:
    for line in f:
        ...

Datei schreiben:

with open('myfile', 'w') as f:
    f.write('Hello')

Datei löschen:

if os.path.exists(targetFile):
    os.remove(targetFile)

JSON

JSON decoden:

import json

# Parse JSON string
jsonData = json.loads('{"some":"json"}')

# Load JSON file
with open('myfile.json') as f:
    jsonData = json.load(f)

JSON encoden:

import json

myJsonData = { 'a': 1 }

# Pretty
encodedJson = json.dumps(myJsonData, sort_keys=True, indent=4).encode('utf-8')

# Compact
encodedJson = json.dumps(myJsonData, sort_keys=True, separators=(',', ':')).encode('utf-8')

XML

Links:

XML parsen (Python 3):

import xml.etree.ElementTree as ElementTree

xml = '<my-xml>...</my-xml>'

rootElem = ElementTree.fromstring(responseBody)

Nervige Namespaces entfernen (Python 3):

def stripNamespaces(elem):
    for el in elem.iter():
        if '}' in el.tag:
            el.tag = el.tag.split('}', 1)[1]  # strip all namespaces

stripNamespaces(rootElem)

Hintergrund: Mit ElementTree muss man immer die vollen Tag-Namen mit Namespaces angeben (z.B. {http://my-namespace}my-tag anstatt my-tag).

Im DOM navigieren (Python 3):

for locationElem in rootElem.findall('.//location'):
    idElem = locationElem.find('.//id')
    idElem.tag   # tag name
    idElem.text  # text

Python als Shell-Skript

Beispiel-Skript zum Verkleinern von Bildern:

#!/usr/bin/python

import math, sys, os, os.path
from subprocess import call

def formatSize(size):
   if (size == 0):
       return '0B'
   sizeNames = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
   i = int(math.floor(math.log(size, 1024)))
   p = math.pow(1024, i)
   s = round(size/p, 2)
   return '%s %s' % (s, sizeNames[i])

def shrink(filename):
    print(filename)

    if os.path.isdir(filename):
        for child in os.listdir(filename):
            shrink(os.path.join(filename, child))
        return

    sizeBefore = os.path.getsize(filename)

    tempFilename = filename + '.temp'

    os.chmod(filename, 0644)
    extension = os.path.splitext(filename)[1].lower()
    if extension == '.png':
        call(['optipng', '-o7', '-silent', filename, '-out', tempFilename])
        call(['pngquant', '--ext=', '--force', '--skip-if-larger', tempFilename])
    elif extension == '.jpg' or extension == '.jpeg':
        call(['jpegtran', '-copy', 'none', '-optimize', '-outfile', tempFilename, filename])
    elif extension == '.svg':
        call(['svgo', '--multipass', '-p', '2', '-o', tempFilename, filename])
    else:
        print('  unsupported file type')
        return

    sizeAfter = os.path.getsize(tempFilename)
    decrease = 1.0 - 1.0 * sizeAfter / sizeBefore
    decreaseFormatted = '%.1f %%' % (100.0 * decrease)
    if sizeAfter == sizeBefore:
        print ('  already optimized')
        os.remove(tempFilename)
    elif decrease < 0.05:
        print ('  keeping original (only ' + decreaseFormatted + ' decrease)')
        os.remove(tempFilename)
    else:
        print('  ' + formatSize(sizeBefore) + ' -> ' + formatSize(sizeAfter) + ' (' + decreaseFormatted + ' decrease)')
        os.remove(filename)
        os.rename(tempFilename, filename)

for filename in sys.argv[1:]:
    if not os.path.isfile(filename) and not os.path.isdir(filename):
        print('ERROR: file not found: ' + filename)
        exit(1)

for filename in sys.argv[1:]:
    shrink(filename)