Essa é para você, que fica desesperado em ter que digitar aquele MALDITO 'self' no início de todos seus métodos. Seus problemas acabaram! Você jamais terá de se preocupar em digitar aqueles quatro caracteres na definição de método novamente. Claro que você terá de se preocupar com muitas outras coisas, mas isso é um mero detalhe.
Basta salvar o código abaixo em um módulo, importar a classe NoSelfType para seu módulo e definir a variável 'metaclass = NoSelfType' no início.
OBS: aos desavisados, esse código é uma brincadeira, feita para mostrar como retirar o self é algo muito mais complicado do que parece! Não vá utilizá-lo em código real!
1 import opcode
2 import types
3
4
5 locals().update(opcode.opmap)
6
7
8 def noself(func, inst):
9 code = func.func_code
10 argdefs = func.func_defaults
11
12 argcount = code.co_argcount
13 nlocals = code.co_nlocals
14 stacksize = code.co_stacksize
15 flags = code.co_flags
16 codestring = code.co_code
17 constants = code.co_consts
18 names = code.co_names
19 varnames = code.co_varnames
20 filename = code.co_filename
21 name = code.co_name
22 firstlineno = code.co_firstlineno
23 lnotab = code.co_lnotab
24 freevars = code.co_freevars
25 cellvars = code.co_cellvars
26
27 varnames = varnames + ('self',)
28 constants = constants + (inst,)
29 nlocals += 1
30
31
32 bcode = map(ord, code.co_code)
33 bcode = [LOAD_CONST,
34 len(constants)-1,
35 0,
36 STORE_FAST,
37 len(varnames)-1,
38 0] + bcode
39
40
41 itercode = iter(enumerate(bcode))
42 earg = 0
43 while 1:
44 try:
45 i, op = itercode.next()
46 if op >= opcode.HAVE_ARGUMENT:
47 oparg = itercode.next()[1] + itercode.next()[1]*256 + earg
48 if op == LOAD_GLOBAL:
49 if names[oparg] == 'self':
50 bcode[i] = LOAD_FAST
51 bcode[i+1] = len(varnames)-1
52 bcode[i+2] = 0
53 except StopIteration:
54 break
55
56 codestring = ''.join(map(chr, bcode))
57
58
59
60 ncode = types.CodeType(argcount, nlocals, stacksize, flags, codestring, constants, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars)
61 nfunc = types.FunctionType(ncode, func.func_globals, func.func_name, argdefs, func.func_closure)
62
63 return nfunc
64
65
66 class NoSelfMethod(object):
67 def __init__(self, func, instance=None, cls=None):
68 self.im_func = func
69 self.im_self = instance
70 self.im_class = cls
71
72 def __get__(self, obj, cls):
73 return NoSelfMethod(self.im_func, obj, cls)
74
75 def __call__(self, *args, **kwds):
76 if self.im_self is None:
77 return self.im_func(*args, **kwds)
78 else:
79 func = noself(self.im_func, self.im_self)
80 return func(*args, **kwds)
81
82
83 class NoSelfType(type):
84 def __new__(mcls, name, bases, dic):
85 for k, v in dic.items():
86 if callable(v):
87 dic[k] = NoSelfMethod(v)
88
89 return type.__new__(NoSelfType, name, bases, dic)
90
91
92 def test():
93
94 class C(object):
95 __metaclass__ = NoSelfType
96
97 def __init__(a, b, c=None):
98 print 'Look mom... no self!'
99 print 'I am', self, 'they called me with', a, b, c
100
101 def m(obj):
102
103 assert obj is self
104
105
106 o = C(1, 2, c='foo')
107 o.m(o)
108
109
110 if __name__ == '__main__':
111 test()