[Tutor] Proxies/Interceptors for file-like objects

Kent Johnson kent37 at tds.net
Thu Feb 19 04:01:34 CET 2009


On Wed, Feb 18, 2009 at 7:51 PM, Emile van Sebille <emile at fenx.com> wrote:

>>>> class open(open):
> ...     def mything(self):
> ...         print "it's my thing"

Hmm. I guess this is Python 3? In 2.6, open is a function and trying
to subclass it gives an error:

In [10]: open
Out[10]: <built-in function open>

In [11]: class myopen(open): pass

   ....:

TypeError: Error when calling the metaclass bases
    cannot create 'builtin_function_or_method' instances

In any event, it's pretty easy to define a generic delegate in Python
using the __getattr__() hook to delegate attribute access. Here is an
example (that assumes all attributes are methods and doesn't actually
do anything other than delegate):
http://code.activestate.com/recipes/252151/

Here is an example using old-style classes that logs attribute access,
both fields and methods:

class LoggingWrapper:
    def __init__(self, instance):
        self.__dict__['_instance'] = instance      # Actual instance

    def __getattr__(self, attrName):
        ''' Log member access '''

        # Get the attribute from the delegate
        attrValue = getattr(self._instance, attrName)

        # Don't log access to private attributes
        if attrName.startswith('_'):
            return attrValue

        if callable(attrValue):
            # Create a delegate function that will log the actual parameters
            def delegate(*args, **kwds):
                params = []
                if args:
                    params.extend(map(repr, args))
                if kwds:
                    params.extend( ['%s=%s' % (key, repr(value)) for
key, value in kwds.items()] )

                paramStr = ', '.join(params)

                __log.debug('%s(%s)' % (attrName, paramStr))

                return attrValue(*args, **kwds)

            return delegate

        else:
            __log.debug(attrName)
            return attrValue

    def __setattr__(self, attr, value):
        __log.debug('%s = %s' % (attr, repr(value)))
        return setattr(self._instance, attr, value)

Kent


More information about the Tutor mailing list