When I was young and stupid - or rather, somewhat younger and more stupid than I am today - I thought the ``self`` parameter was some oversight on Guido's part. I mean, what's the point? It makes method definition more cumbersome, and serves no real purpose; the same thing is automatically available in *every* object-oriented programming language, *ever*; even in Javascript, for heaven's sake! And so, I sought out to destroy it: take a class, iterate over its methods, and patch them so that they get ``self`` without having to define it explicitly. Something like this: ```python class A: def __init__(x): self.x = x def f(): return self.x + 1 a = A(1) assert a.x == 1 assert a.f() == 2 ``` ![pause](/media/images/pause.png) Many people, when they hear "take a class and do something to it", immediately think: "On no, here come metaclasses". The truth is, this *can* be done with metaclasses, but it's usually much simpler to use a decorator instead. For example, let's write one that doubles a class methods' return values: ```python def double(cls): for name, function in vars(cls).items(): if not callable(function): continue setattr(cls, name, double_function(function)) return cls def double_function(function): @functools.wraps(function) def doubled(*args, **kwds): return 2*function(*args, **kwds) return doubled @double class A: def one(self): return 1 def two(self): return 2 a = A() assert a.one() == 2 assert a.two() == 4 ``` Except, we don't want to be doubling return values; we want to be ridding the world of all these useless selves. (That sounded harsh.) ![pause](/media/images/pause.png) First, have at a look at this code: what do you think will happen? ```python def f(): locals()['x'] = 1 print(x) ``` I thought it would print ``1``; but actually, it ``NameError``s with ``global name 'x' is not defined``. Notice that *global*? When Python evaluates this function, it doesn't see any ``x`` in its code, so it assumes it must be a global variable, and generates *bytecode* - yeah, Python actually *compiles* its functions - that treats the ``print(x)`` statement as "get me the global variable ``x`` and print it". So, even though we dynamically add ``x`` to its local variables, ``f`` never even looks there; and since we haven't defined a global ``x``, we get a ``NameError``. So if we're going to define our methods without ``self`` in their signature, Python is going to assume it's a global variable; in other words, all we have to do is hook these methods' global scopes and put ``self`` there. ```python def selfless(cls): for name, function in vars(cls).items(): if not callable(function): continue setattr(cls, name, add_self(function)) return cls def add_self(function): @functools.wraps(function) def with_self(self, *args, **kwds): function.__globals__['self'] = self return function(*args, **kwds) return with_self ``` This works, but it feels a bit crude, doesn't it? Polluting the global namespace like that; let's at least clean up after ourselves. ```python def with_self(self, *args, **kwds): # Backup globals()['self'] if it exists... prev = function.__globals__.pop('self', None) # Now switch it! function.__globals__['self'] = self try: return function(*args, **kwds) finally: # Clean up... del function.__globals__['self'] # And restore the backup, if necessary. if prev is not None: function.__globals__['self'] = prev ``` But what if there *was* a self in the global scope, that just so happened to be ``None``? We just gone and deleted it! To avoid this, we can use the following trick (and in fact, it's a useful trick for whenever you need to distinguish an undefined value from a ``None`` value; pretty much like Javascript has ``undefined`` and ``null``): ```python undefined = object() def with_self(self, *args, **kwds): prev = function.__globals__.pop('self', undefined) function.__globals__['self'] = self try: return function(*args, **kwds) finally: del function.__globals__['self'] if prev is not undefined: function.__globals__['self'] = prev ``` This still isn't ideal: for example, it's not thread safe (we're changing the global scope, which is shared by all the threads, so selves are going to be overwriting each other left and right); and if our method happens to call some function, which *was* using the ``self`` global variable, it's going to be quite surprised (although, this one isn't very likely; I mean, who has a global variable named ``self``? That's just weird). But hey, it works! ```python @selfless class A: def __init__(x): self.x = x def f(): return self.x + 1 a = A(1) assert a.x == 1 assert a.f() == 2 ``` ![pause](/media/images/pause.png) In a [following post](/post/selfless-classes-godless-hacks), we're going to do some much darker magic, and get decorator working by rewriting function code on the fly. Stay tuned, and check out the code at [Github](https://github.com/dan-gittik/selfless).