Метакласовете в Python са много яко нещо. Макар все още да не ми се е наложило да напиша дори един такъв за работата си, са много полезен източник на забавления. Сега ще ви покажа как с малко остроумие може да дефинирате класове по следния интересен начин:
Python
-
class Person(object):
-
__metaclass__ = selfless
-
def __init__(name, age):
-
self.name = name
-
self.age = age
-
-
def __repr__():
-
return "Person(%s, %d)" % (repr(self.name), self.age)
-
-
def sayHi():
-
print "Hello, I’m %s and I’m %d years old" % (self.name, self.age)
-
-
def rename(newName):
-
self.name = newName
Интересното? Въобще не ви се налага да пишете self пред имената на методите.
Как го постигам? Доста просто:
Python
-
from types import FunctionType
-
-
class selfless(type):
-
def __new__(cls, name, bases, classDict):
-
for attr in classDict:
-
if not isinstance(classDict[attr], FunctionType): continue
-
classDict[attr] = selflessWrapper(classDict[attr])
-
return type.__new__(cls, name, bases, classDict)
-
-
-
def selflessWrapper(func):
-
def wrapper(self, *args, **kwargs):
-
hadSelf, oldSelf = func.func_globals.has_key(’self’), \
-
func.func_globals.get(’self’)
-
func.func_globals[’self’] = self
-
returnValue = func(*args, **kwargs)
-
if hadSelf:
-
func.func_globals[’self’] = oldSelf
-
else:
-
del func.func_globals[’self’]
-
return returnValue
-
wrapper.func_name = func.func_name + "_wrapper"
-
return wrapper
В общи линии, създавам нов метаклас, който барва всички функции на инстанциите си. Разширява ги с по един аргумент, а в глобалната им област на видимост добавя едно ново име (self), което след това възстановява. В резултат, всяка функция вижда self, а самия клас вижда функциите като такива с един аргумент повече. Едва ли е нужно да казвам, че цялата врътка става във selflessWrapper.