Why are so many built-in types inheritable?

Ziga Seilnacht ziga.seilnacht at gmail.com
Sat Mar 25 16:58:17 EST 2006


Fabiano Sidler wrote:

[snipped]

> The problem with this is that the func_code attribute would contain
> the code of PrintingFunction instead of func. What I wanted to do, is
> to keep the original behaviour, i.e. set the variable __metaclass__ to
> DebugMeta and so get debug output, without changing a function and
> getting the original function's code object by the func_code
> attribute, not PrintigFunction's one. That's why I *must* inherit from
> <type 'function'>.

No, you don't have to:

>>> import new
>>> import types
>>> class DebugFunction(object):
...     def __init__(self, func):
...         object.__setattr__(self, 'func', func)
...     def __get__(self, obj, objtype):
...         return new.instancemethod(self, obj, objtype)
...     def __call__(self, *args, **namedargs):
...         print args, namedargs
...         func = object.__getattribute__(self, 'func')
...         return func(*args, **namedargs)
...     def __getattribute__(self, name):
...         func = object.__getattribute__(self, 'func')
...         return getattr(func, name)
...     def __setattr__(self, name, value):
...         func = object.__getattribute__(self, 'func')
...         setattr(func, name, value)
...     def __delattr__(self, name):
...         func = object.__getattribute__(self, 'func')
...         delattr(func, name)
...
>>> class DebugMeta(type):
...     def __new__(meta, name, bases, dict):
...         for name, obj in dict.iteritems():
...             if isinstance(obj, types.FunctionType):
...                 dict[name] = DebugFunction(obj)
...         return type.__new__(meta, name, bases, dict)
...
>>> class Example(object):
...     __metaclass__ = DebugMeta
...     def spam(self, *args, **namedargs):
...         """Spam spam spam spam. Lovely spam! Wonderful spam!"""
...         pass
...
>>> e = Example()
>>> e.spam('eggs', anwser=42)
(<__main__.spam object at ...>, 'eggs') {'anwser': 42}
>>> e.spam.__doc__
'Spam spam spam spam. Lovely spam! Wonderful spam!'
>>> e.spam.im_func.func_code
<code object spam at ..., file "<stdin>", line 3>

 
> Greetings,
> F. Sidler

Ziga




More information about the Python-list mailing list