0
I’ve been watching the videos (example) by Luciano Ramalho on Descriptors with metaclass.
I wanted to know the advantage of this model in relation to the more traditional implementation of Descriptors as that example in the documentation:
class RevealAccess(object):
"""A data descriptor that sets and returns values
normally and prints a message logging their access.
"""
def __init__(self, initval=None, name='var'):
self.val = initval
self.name = name
def __get__(self, obj, objtype):
print('Retrieving', self.name)
return self.val
def __set__(self, obj, val):
print('Updating', self.name)
self.val = val
>>> class MyClass(object):
... x = RevealAccess(10, 'var "x"')
... y = 5
...
>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> m.x
Retrieving var "x"
20
>>> m.y
5
I made a test and to me it seemed to work equal. I also noticed that in the example of documentation the methods getattr and setattr are not used as in example luciano:
class Quantidade(object):
def __init__(self)
self.set_nome(self.__class__.__name__, id(self))
def set_nome(self, prefix, key):
self.nome_alvo = '%s_%s' % (prefix, key)
def __get__(self, instance, owner):
return getattr(instance, self.nome_alvo)
def __set__(self, instance, value):
if value > 0:
setattr(instance, self.nome_alvo, value)
else:
raise ValueError('valor deve ser > 0')
class ModeloMeta(type):
def __init__(cls, nome, bases, dic):
super(ModeloMeta, cls).__init__(nome, bases, dic)
for chave, attr in dic.items():
if hasattr(atr, 'set_nome'):
attr.set_nome('__' + nome, chave)
class Modelo(object):
__metaclass__ = ModeloMeta
class ItemPedido(Modelo):
peso = Quantidade()
preco = Quantidade()
def __init__(self, descricao, peso, preco):
self.descricao = descricao
self.peso = peso
self.preco = preco
yes- that’s right - the
__set_name__
reduces the most obvious use for metaclasses, and their existence makes the use of the same optional in most cases.– jsbueno