Метакласовете в 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 пред имената на методите.
Как го постигам? Доста просто:
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.