What Features of Python Do I Use?
It’s easy to answer the question in this post’s title
for the Python version Software Design by Example
using Python’s ast
module:
import ast
import sys
from collections import Counter
def main():
seen = Counter()
for filename in sys.argv[1:]:
scrape(filename, seen)
for count, name in sorted(seen.items(), key=lambda x: x[1], reverse=True):
print(name, count)
def scrape(filename, seen):
with open(filename, "r") as reader:
tree = ast.parse(reader.read(), filename=filename)
for node in ast.walk(tree):
seen[node.__class__.__name__] += 1
if __name__ == "__main__":
main()
The results shown below reveal that
the book uses a rather small subset of Python’s features.
These tables is misleading, though,
since things like decorators and else
don’t show up.
Still,
I think these numbers show that:
- I’m pretty conservative in my Python coding.
- It’s possible to teach a lot about design without using a lot of language features.
- Which implies that it’s possible do a lot of design with a fairly small language.
As I wrote a couple of days ago, I’m not going to write another programming book. If I had it all to do over again, though, I’d think very seriously about doing just one volume in Lua: Roberto Ierusalimschy and his team have done us all a service in resisting the bloat that almost every other language has succumbed to.
Count | Name | Comment |
---|---|---|
11619 | Load | Read a value |
9667 | Name | Variable or function name |
3874 | Constant | Constant number or string |
3437 | Call | Call a function or method |
2579 | Attribute | Reference an object attribute with . notation |
2048 | Store | Write a value (17% as common as reading) |
1416 | Assign | Assignment (which includes updating as well as initial definition) |
1103 | FunctionDef | I define a lot of little functions… |
803 | Subscript | […] element reference |
526 | Return | Huh: only about half of my functions actually return something explicitly |
469 | Eq | Value equality |
371 | List | Defining a new list |
327 | If | elif and else don’t show up separately |
276 | JoinedStr | A bunch of f-strings |
214 | ImportFrom | My example programs import things from each other a lot |
213 | Tuple | Tuple definition |
173 | For | Loops |
163 | Dict | Explicit dictionaries |
150 | ClassDef | I define many fewer classes than functions in this book |
148 | Import | Mostly standard libraries |
79 | Slice | A lot of these are sys.argv[1:] … |
72 | AugAssign | += and its friends |
68 | ListComp | I still prefer loops to list comprehensions |
40 | With | I use with statements primarily for file I/O and mock objects in tests |
35 | Starred | Spreading lists |
33 | Pass | Mostly placeholders as I’m developing code in stages during a tutorial |
32 | Raise | I probably should have included more about exception handling… |
29 | While | 17% as many while loops as for loops |
24 | ExceptHandler | See note above about exceptions |
22 | DictComp | I could have written more of these, but the code can be hard to read |
18 | Try | See note above about exceptions |
12 | Set | Turns out constant sets are pretty rare |
11 | SetComp | See above |
11 | Continue | Surprised that there are more continue than break |
11 | Lambda | Almost all as key arguments to sorting |
7 | Break | See note above about continue |
1 | Del | Removing a breakpoint from a dictionary |
1 | Global | I could (and should) get rid of this… |
And here are the uninteresting bits (e.g., intermediate nodes in the parse tree or specific arithmetic operators):
Count | Name | Count | Name | Count | Name |
---|---|---|---|---|---|
961 | Expr | 57 | In | 8 | BitOr |
698 | Compare | 55 | USub | 7 | BitAnd |
485 | Assert | 41 | Lt | 7 | Div |
296 | FormattedValue | 40 | Sub | 7 | IsNot |
248 | Module | 37 | NotEq | 4 | Or |
217 | BinOp | 36 | LtE | 4 | RShift |
113 | UnaryOp | 31 | Gt | 3 | NamedExpr |
26 | GeneratorExp | 28 | NotIn | 3 | GtE |
21 | BoolOp | 17 | And | 2 | FloorDiv |
20 | IfExp | 14 | Pow | 2 | LShift |
136 | Add | 12 | Is | 1 | Invert |
58 | Mult | 11 | Mod | 1 | Delete |
57 | Not |
Update: in memory of Niklaus Wirth, Dana Sibera has reproduced the classic Apple Pascal poster (see below). Like I said, I’m not going to write another programming book, but if I did, I’d want to use a language whose grammer is no more complicated than this.