A lot of the Python code you will come across is open source. The whole point is to distribute it freely, share knowledge and let people play around with it and learn from it.
Sometimes, though, you might want to prevent the end-user from reading the code. Maybe you are selling commercial software or maybe you just want to share the solution to a tricky coding challenge with your friends without giving the game away.
Whatever your reasons, there are a few approaches you can take:
One is obfuscation. I like a package called pyobfuscate. It transforms your normal and clearly written (right?) Python source code into new source code that is hard to read, by making changes to whitespace and names, stripping comments, removing functions, etc.
The package doesn’t seem to be on PyPI, but you can install it from the Github repo:
Let’s try it out. Save the following code in example.py :
Obfuscate it using the pyobfuscate command, which should be on your path now that you have installed the package:
Thee obfuscated code will be printed to the console:
That’s pretty illegible!
Unfortunately pyobfuscate only works on one source file at a time, so it’s not really suitable for large projects. It also appears to only work with Python 2 at the moment.
Another, arguably easier, method is to just distribute the .pyc files. The Python standard library includes a compileall module that can scan your source directory and compile all of your files into Python bytecode. Then you can distribute them without the source files. The .pyc files can still be decompiled into source code, but the code will not be as readable as it was before.
One problem with this method is that the initial .py script that you run cannot be compiled in this way. You can solve this problem by making a simple wrapper script that gives away no information about your program.
These two methods are really just a deterrent, not a secure way of hiding the code.
If you want something a bit more robust, you should take a look at Nuitka, which compiles Python code to C++, so you can compile that and just distribute the executable. It seems to be broadly compatible with different libraries and different versions of Python.