Себичен питон

Метакласовете в Python са много яко нещо. Макар все още да не ми се е наложило да напиша дори един такъв за работата си, са много полезен източник на забавления. Сега ще ви покажа как с малко остроумие може да дефинирате класове по следния интересен начин:

Python [Show Plain Code]:
  1. class Person(object):
  2.     __metaclass__ = selfless
  3.     def __init__(name, age):
  4.         self.name = name
  5.         self.age = age
  6.  
  7.     def __repr__():
  8.         return "Person(%s, %d)" % (repr(self.name), self.age)
  9.  
  10.     def sayHi():
  11.         print "Hello, I’m %s and I’m %d years old" % (self.name, self.age)
  12.  
  13.     def rename(newName):
  14.         self.name = newName

Интересното? Въобще не ви се налага да пишете self пред имената на методите.

Как го постигам? Доста просто:

Python [Show Plain Code]:
  1. from types import FunctionType
  2.  
  3. class selfless(type):
  4.     def __new__(cls, name, bases, classDict):
  5.         for attr in classDict:
  6.             if not isinstance(classDict[attr], FunctionType): continue
  7.             classDict[attr] = selflessWrapper(classDict[attr])
  8.         return type.__new__(cls, name, bases, classDict)
  9.  
  10.  
  11. def selflessWrapper(func):
  12.     def wrapper(self, *args, **kwargs):
  13.         hadSelf, oldSelf = func.func_globals.has_key(’self’), \
  14.                 func.func_globals.get(’self’)
  15.         func.func_globals[’self’] = self
  16.         returnValue = func(*args, **kwargs)
  17.         if hadSelf:
  18.             func.func_globals[’self’] = oldSelf
  19.         else:
  20.             del func.func_globals[’self’]
  21.         return returnValue
  22.     wrapper.func_name = func.func_name + "_wrapper"
  23.     return wrapper

В общи линии, създавам нов метаклас, който барва всички функции на инстанциите си. Разширява ги с по един аргумент, а в глобалната им област на видимост добавя едно ново име (self), което след това възстановява. В резултат, всяка функция вижда self, а самия клас вижда функциите като такива с един аргумент повече. Едва ли е нужно да казвам, че цялата врътка става във selflessWrapper.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*