Weird things you can, but probably shouldn't do in Python
Integers between -5 and 256 can have their values swapped.
I am at a loss when I consider where this would be useful. Nevertheless, did you know that in Python you can change what numbers fundamentally mean?
# Code squashed for # the benefit of # mobile readers import ctypes # change 100 to 99 ctypes.cast(id(100), ctypes.POINTER( ctypes.c_int)) = 99 # change 98 to 101 ctypes.cast(id(98), ctypes.POINTER( ctypes.c_int)) = 101 if 100 == 99: print('wait a minute') if 98 > 100: print('Human sacrifice, ' 'dogs and cats living together, ' 'mass hysteria.')
wait a minute Human sacrifice, dogs and cats living together, mass hysteria.
The reason this works is because in the Python interpreter creates an instance of all the numbers between -5 and 256 and stores them in an array. ctypes allows us to access this underlying array and shuffle things around.
BaseException will almost always be uncaught.
If you want to catch every possible exception in Python, you generally do it like this:
try: raise Exception except Exception: print('the day is saved.')
However, this practice can be considered un-pythonic:
When catching exceptions, mention specific exceptions whenever possible
PEP 8 also informs us
Derive exceptions from Exception rather than BaseException. Direct inheritance from BaseException is reserved for exceptions where catching them is almost always the wrong thing to do.
So, what happens when you use BaseException as opposed to Exception?
try: raise BaseException except Exception: print('this never happens.')
Traceback (most recent call last): File "did_I_do_that.py", line 2, in <module> raise BaseException
This can be taken to the next logical step. If you inherit from BaseException, as opposed to Exception, you can retain this behavior.
class CatchMeIfYouCan(BaseException): pass try: raise CatchMeIfYouCan except Exception: print('neither does this.')
Traceback (most recent call last): File "stefan.py", line 5, in <module> raise CatchMeIfYouCan
In order to catch these, you simply must use a bare except clause.
try: raise CatchMeIfYouCan except: print('this works')
That isn't ideal though, as this will also catch SystemExit, so calls to sys.exit() will do nothing.
try: sys.exit() except: print("I'm still here.")
I'm still here.
It's possible to read or even modify the contents of other modules programmatically.
This probably has no practical use, but can you guess what Rumpelstiltskin does?
import imp def rumpelstiltskin(): magic = ['W', 358, 19, 19, 1, 74, 358, 77, 9, 358, 13, 43, 26] data = imp.find_module('this') data = open(data, 'r').read() for fairy_dust in magic: if isinstance(fairy_dust, str): print(fairy_dust) else: print(data[fairy_dust])
It's a terrible way to print my name.
W i l l c i p r i a n o
What I'm doing here is looking up the 'this', a Python easter egg. Importing 'this' prints The Zen of Python. (after it decodes it from rot13 that is)
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
imp allows me to find the module location on the disk and I can read it like any other file. Can I edit it like any other file as well?
import imp def pwnthon(content): module = imp.find_module('this') module = open(module, 'w') module.write(content) pwnthon("""print( "He's not the Messiah - he's a very naughty boy")""")
Next I import this
He's not the Messiah - he's a very naughty boy
Yes, I can. Although in my Windows 10 VM, I needed to run PyCharm as admin. Otherwise, I received a permission denied error. These changes are permanent, so this kind of monkey patching is a bad idea.