associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Revisão 2e 2005-07-14 18:58:12

Excluir mensagem

AutomatizarAtributosSlots

Metaclasse para definir automaticamente __slots__ e todos os argumentos passados que iniciem com o caracter '_'

   1 class AutoSlots(type):
   2     def __new__(meta, name, bases, data):
   3         if '__init__' in data:
   4             slots = data.get('__slots__', [])
   5             init = data['__init__']
   6             varnames = init.func_code.co_varnames
   7             
   8             for var in varnames:
   9                 if var.startswith('_'):
  10                     var = var[1:]
  11                     if var not in slots:
  12                         slots.append(var)
  13 
  14             if slots:
  15                 data['__slots__'] = slots
  16 
  17         cls = super(AutoSlots, meta).__new__(meta, name, bases, data)
  18         super(AutoSlots, cls).__init__(cls, name, bases, data)
  19 
  20         return cls
  21 
  22 
  23 class AutoAttrs(type):
  24     def __call__(cls, *args, **kwds):
  25         o = object.__new__(cls, *args, **kwds)
  26         if hasattr(cls, '__init__'):
  27             names = cls.__init__.func_code.co_varnames
  28             attrs = zip(names[1:], args)
  29             for k, v in attrs:
  30                 if k.startswith('_'):
  31                     setattr(o, k[1:], v)
  32 
  33         cls.__init__(o, *args, **kwds)
  34 
  35         return o
  36 
  37 
  38 class AutoSlotsAttrs(AutoAttrs, AutoSlots):
  39     pass
  40 
  41 
  42 #teste:
  43 
  44 import unittest
  45 
  46 class Sample(object):
  47     __metaclass__ = AutoSlotsAttrs
  48     def __init__(self, _a, _b, c, d=None):
  49         assert self.a + self.b == c
  50     
  51 
  52 class Test(unittest.TestCase):
  53     def testAttributes(self):
  54         o = Sample(1, 2, 3, d=4)
  55 
  56         self.assertEqual(o.a, 1)
  57         self.assertEqual(o.b, 2)
  58 
  59         self.assert_(not hasattr(o, 'c'))
  60 
  61         self.assert_(hasattr(o, '__slots__'))
  62         self.assertRaises(AttributeError, setattr, o, 'e', 10)
  63 
  64 
  65 if __name__ == '__main__':
  66     unittest.main()