Standard modules ↩
- os
- shutil
- os.path
- glob
- random
- math
- datetime
- colorsys
- zipfile
- subprocess
- xml.etree.ElementTree
- string
- json
- plistlib
- difflib
- More standard modules
Python comes with batteries included – it has (almost) everything you need out-of-the-box. Distributions of Python include modules from the Python Standard Library, which provide a wide range of tools for common problems in everyday programming – for example file system access, numerical and mathematical functions, unicode text processing, dealing with dates and calendars, reading / writing multiple data formats, serving web pages, generating random numbers, and a lot more.
This page shows selected examples of useful functions available in various standard modules. Follow the links to the official documentation of each module for more information.
os
The os
module contains functions that deal with the file system.
import os
- os.listdir
-
Lists the contents of a folder:
>>> os.listdir('/myFolder')
- os.walk
-
Recursively lists the contents of a folder and all its subfolders:
aFolder = '/myFolder' for path, folders, files in os.walk(aFolder): print(path) print(folders) print(files) print('-'*30)
- os.getcwd
-
Returns the folder where the current script is running (current working directory):
>>> os.getcwd()
- os.mkdir
-
Creates a new folder:
newFolder = "/Users/myUsername/Desktop/test" os.mkdir(newFolder)
- os.makedirs
-
Creates a folder and all parent folders in a given path:
newFolder2 = "/Users/myUsername/Desktop/test2/aSubfolder" os.makedirs(newFolder2)
- os.rename
-
Renames a folder or file:
oldFile = "/Users/myUsername/Desktop/image.png" newFile = "/Users/myUsername/Desktop/imageNew.png" os.rename(oldFile, newFile)
- os.remove
-
Removes a file:
filePath = "/Users/myUsername/Desktop/test3/image.png" os.remove(filePath)
- os.rmdir
-
Removes an empty folder:
os.rmdir(newFolderName)
To remove a folder and everything inside it, use
shutil.rmtree
(see below).
shutil
The shutil
module offers functions to copy and remove collections of files.
import shutil
- copytree
-
Copies a folder and all its contents to a given path, creating missing parent folders.
srcFolder = "/Users/myUsername/Desktop/test1" dstFolder = "/Users/myUsername/Desktop/backup/test1" shutil.copytree(srcFolder, dstFolder)
- rmtree
-
Delete a folder and all its contents.
shutil.rmtree(srcFolder)
os.path
The os.path
module contains functions for manipulating file and folder names.
- os.path.exists
-
Checks if a file or folder exists, returns a bool:
>>> os.path.exists('/myFile.png')
- os.path.basename
-
Returns the file name for a given path, without the parent folder:
>>> filePath = "/Users/myUsername/Desktop/test3/image.png" >>> os.path.basename(filePath)
image.png
- os.path.dirname
-
Returns the parent folder for a given file path:
os.path.dirname(filePath)
/Users/myUsername/Desktop/test3
- os.path.split
-
Splits a given file path into parent folder and file name:
folder, fileName = os.path.split(filePath)
- os.path.splitext
-
Splits a file path into root and extension:
>>> os.path.splitext(filePath)
('/Users/myUsername/Desktop/test3/image', '.png')
glob
The glob
module finds all file or folder names matching a specified pattern.
The example script below returns a list of all UFO files in a given folder:
>>> import glob
>>> glob.glob('/aFolder/*.ufo')
random
The random
module provides functions to generate pseudo-random numbers, make random choices, etc.
from random import random, randint, choice # ... etc.
- random
-
Returns a random
float
between0.0
and1.0
:>>> for i in range(5): ... random()
0.1440220412035288 0.6030806336013335 0.23406747728785426 0.12986516342850718 0.5555918432876255
- randint
-
Returns a random
int
between two given integers:>>> for i in range(5): ... randint(10, 70)
17 59 27 40 34
- uniform
-
Returns a random
float
between two given numbers:>>> for i in range(5): ... uniform(0.2, 12)
9.377996146219418 11.67729261822652 9.499059365948389 5.330554497768862 8.164767529218107
- choice
-
Returns one randomly selected item from a given list.
>>> fruits = ['apple', 'orange', 'banana', 'lemon', 'strawberry'] >>> for i in range(5): ... choice(fruits)
lemon banana strawberry orange orange
- shuffle
-
Shuffles the items of a given list in place.
for i in range(5): shuffle(fruits) print(fruits
['apple', 'banana', 'orange', 'lemon', 'strawberry'] ['strawberry', 'lemon', 'banana', 'apple', 'orange'] ['apple', 'lemon', 'strawberry', 'orange', 'banana'] ['apple', 'banana', 'orange', 'lemon', 'strawberry'] ['lemon', 'banana', 'apple', 'orange', 'strawberry']
- seed
-
Initializes the random number generator.
from random import random, seed seed(3) print(random())
The result of this script will always be:
0.32383276483316237
This makes it possible to reproduce random values generated with a script!
math
The math
module provides several mathematical functions and constants.
from math import *
- sqrt
-
Returns the square root of a number.
>>> sqrt(81)
9.0
- floor
-
Returns the largest integer which is less than or equal to a given number.
>>> floor(4.80)
4
- ceil
-
Returns the smallest integer which is greater than or equal to a given number.
>>> ceil(4.80)
5
- pi
-
The mathematical constant π (pi).
>>> from math import pi >>> pi
3.141592653589793
- sin, cos, tan, etc.
-
Return the sine, cosine, tangent etc. for a given angle.
The DrawBot script below shows an example of vector math, using
cos
andsin
to calculate new coordinates from an origin point, angle and distance.from math import sin, cos x1, y1 = 100, 100 distance = 800 angle = 60 x2 = x1 + distance * sin(radians(angle)) y2 = y1 + distance * cos(radians(angle)) stroke(1, 0, 0) line((x1, y1), (x2, y2))
Here’s another example of vector math, using the trigonometric functions
hypot
(hypothenuse) andatan2
(arc tangent) to calculate the distance and angle between two points.from math import hypot, atan2 x1, y1 = 100, 100 x2, y2 = 500, 480 distance = hypot(x2 - x1, y2 - y1) angle = degrees(atan2(y2 - y1, x2 - x1))
- use
radians()
to convert angles in degrees to radians - use
degrees()
to convert angles in radians to degrees
- use
datetime
The datetime
module supplies classes for manipulating dates and times.
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
2020-03-19 09:19:24.797088
Date objects support a strftime(format)
method to create a string representation of time and date using format codes. For example:
>>> now.strftime("%x %X")
>>> now.strftime("%d %B %Y %H:%M %A")
03/19/2020 09:19:24
19 March 2020 09:19 Thursday 079
See strftime() and strptime() Behavior for the full set of format codes available.
colorsys
The colorsys
module contains functions to convert color values between different color systems (RGB, YIQ, HLS, HSV).
The DrawBot script below uses colorsys
to produce a range of hues.
from colorsys import hsv_to_rgb
size(600, 120)
steps = 15
w = width() / steps
x = y = 0
for i in range(steps):
hue = i * 1.0 / steps
R, G, B = hsv_to_rgb(hue, 1.0, 1.0)
fill(R, G, B)
rect(x, y, w, height())
x += w
zipfile
The zipfile
module provides tools to create, read, write, append, and list a ZIP file.
- Create a zip file from a given folder
-
import os from zipfile import ZipFile folder = 'someFolder' zipPath = os.path.join(os.path.dirname(folder), 'myZipFile.zip') with ZipFile(zipPath, 'w') as myZip: for root, dirs, files in os.walk(folder): for fileName in files: filePath = os.path.join(root, fileName) myZip.write(filePath, os.path.relpath(filePath, folder))
- Expand the contents of a zip file into a folder
-
from zipfile import ZipFile zipPath = 'myZipFile.zip' dstPath = '/someFolder' with ZipFile(zipPath, 'r') as myZip: myZip.extractall(dstPath)
subprocess
The subprocess
module allows you to run new processes, for example to execute command-line tools from a script.
The script below converts a VFB font to UFO by calling a locally installed vfb2ufo.
import subprocess
cmds = ['/usr/local/bin/vfb2ufo', '/aFolder/myFont.vfb']
p = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
output, errors = p.communicate()
print(output)
xml.etree.ElementTree
The xml.etree.ElementTree
module implements a simple API for parsing and creating XML data.
- Parse an XML file
-
import xml.etree.ElementTree as ET xmlPath = '/aFolder/myFont.ufo/glyphs/a.glif' tree = ET.parse(xmlPath)
- Get root tag and attributes
-
root = tree.getroot() print(root.tag, root.attrib)
glyph {'name': 'a', 'format': '2'}
- Get all children of an element
-
for child in root: print(child.tag, child.attrib)
advance {'width': '475'} unicode {'hex': '0061'} outline {} lib {}
- Find all children with a given tag
-
for elem in root.findall('outline'): print(elem.tag)
- Iterate recursively over all sub-trees
-
for elem in root.iter('point'): print(elem.tag)
- Find element and set a value for an attribute
-
root.find('advance').attrib['width'] = 700
- Save changes to XML file
-
tree.write(xmlPath)
string
The string
module contains some useful lists of characters:
>>> import string
>>> string.ascii_lowercase
abcdefghijklmnopqrstuvwxyz
>>> string.ascii_uppercase
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>> string.digits
0123456789
>>> string.punctuation
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
json
The json
module provides tools for reading and writing JSON files.
- json.loads
-
Loads data from a JSON file into a dictionary.
import json jsonPath = 'somedata.json' with open(jsonPath, 'r', encoding='utf-8') as f: data = json.loads(f.read()) print(data)
- json.dumps
-
Encodes a Python object hierarchy into JSON format.
The example below also saves a
.json
file at a given path.fontinfo = { 'familyName' : 'My Font', 'versionMajor' : 1, 'versionMinor' : 3, 'openTypeNameDesignerURL' : 'http://mywebsite.com/', } jsonPath = 'fontinfo.json' with open(jsonPath, 'w', encoding='utf-8') as f: data = json.dumps(fontinfo) f.write(data)
plistlib
The plistlib
module provides an interface for reading and writing the property list files used by macOS.
Property lists are also used by the UFOUnified Font Object. A cross-platform, cross-application, human-readable, future-proof format for storing font data. format to store various kinds of metadata, for example fontinfo.plist, kerning.plist, groups.plist, etc.
- plistlib.load
-
Loads data from a
.plist
file into a dictionary.import plistlib plistPath = 'somedata.plist' with open(plistPath, 'rb') as f: data = plistlib.load(f) print(data)
- plistlib.dump
-
Write an object to a
.plist
file.fontinfo = { 'familyName' : 'My Font', 'versionMajor' : 1, 'versionMinor' : 3, 'openTypeNameDesignerURL' : 'http://mywebsite.com/', } plistPath = 'fontinfo.plist' with open(plistPath, 'wb') as f: plistlib.dump(fontinfo, f)
difflib
The difflib
module provides classes and functions for comparing sequences. It can be used to show the differences between two versions of a text-based file – such as two .glif
files, as in the example below.
import difflib
glifPath1 = 'myFont1.ufo/glyphs/a.glif'
with open(glifPath1, 'r') as f:
glifSrc1 = f.readlines()
glifPath2 = 'myFont2.ufo/glyphs/a.glif'
with open(glifPath2, 'r') as f:
glifSrc2 = f.readlines()
uniDiff = difflib.unified_diff(glifSrc1, glifSrc2)
print(''.join(list(uniDiff)))
---
+++
@@ -1,18 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<glyph name="a" format="2">
- <advance width="500"/>
+ <advance width="514.9054171954316"/>
<outline>
<contour>
<point x="152.70780456852776" y="609.2342163705584" type="line"/>
<point x="65.2954473350253" y="245.02359612944178" type="line"/>
- <point x="334.9054171954316" y="151.91108819796978" type="line"/>
+ <point x="434.9054171954316" y="151.91108819796978" type="line"/>
<point x="423.27093908629433" y="603.8090894670054" type="line"/>
</contour>
</outline>
- <lib>
- <dict>
- <key>public.markColor</key>
- <string>0,1,0,1</string>
- </dict>
- </lib>
</glyph>
Several diff modes are available, including an HTML diff with colors.
D = difflib.HtmlDiff()
html = D.make_file(glifSrc1, glifSrc2)
print(html)
You can use difflib to compute the differences between GLIF files. For example:
import difflib
import vanilla
from mojo.UI import CodeEditor
glyph = CurrentGlyph()
before = glyph.dumpToGLIF()
for contour in glyph:
contour.autoStartSegment()
after = glyph.dumpToGLIF()
D = difflib.Differ()
diff = D.compare(before.split('\n'), after.split('\n'))
diffText = '\n'.join(diff)
w = vanilla.Window((800, 400), minSize=(300, 400))
w.e = CodeEditor((0, 0, 0, 0), diffText, readOnly=True, lexer="xml")
w.open()
More standard modules
The Python Standard Library includes many other modules – see the documentation for more information about each module.