code explanation

Rodrick Brown rodrick.brown at gmail.com
Mon Jan 14 23:51:40 EST 2013


On Mon, Jan 14, 2013 at 11:38 PM, Steven D'Aprano <
steve+comp.lang.python at pearwood.info> wrote:

> On Mon, 14 Jan 2013 23:00:16 -0500, Rodrick Brown wrote:
>
> > Can someone explain what's going on here.
> >
> > def _build_magic_dispatcher(method):
> >     def inner(self, *args, **kwargs):
> >         return self.__dict__[method](*args, **kwargs)
> >     inner.__name__ = method
> >     return inner
> >
> > Thanks.
>
>
> This is a factory function, probably intended to be used as a decorator:
>
> class K:
>     @_build_magic_dispatcher
>     def something(self, x, y, z): ...
>
> except that it appears to be broken. It seems to be expecting a *string*,
> the name of a method, despite the function parameter claiming to require
> a method itself. So maybe you use it like this:
>
> class K:
>     def __init__(self):
>         self.parrot = _build_magic_dispatcher("parrot")
>
>
> or something similar. Without seeing the context, it's hard for me to
> tell whether it works or is broken. I suspect it is broken, or useless,
> or both.
>
> So, this factory function seems to take the *name* of a method as
> argument. Then it builds an inner method, which accepts arbitrary
> arguments (args and kwargs), renames the inner method to the name you
> passed as argument, and returns it.
>
>
Thanks Steven, here is the full context of the code. I'm trying to
understand what exactly the author is trying to accomplish here.

import sys

PY3K = sys.version_info >= (3,)


methods = set([
    "__iter__",
    "__len__",
    "__contains__",

    "__lt__",
    "__le__",
    "__eq__",
    "__ne__",
    "__gt__",
    "__ge__",

    "__add__",
    "__and__",
    "__divmod__",
    "__floordiv__",
    "__lshift__",
    "__mod__",
    "__mul__",
    "__or__",
    "__pow__",
    "__rshift__",
    "__sub__",
    "__truediv__",
    "__xor__",
])
if PY3K:
    methods.add("__next__")
    methods.add("__bool__")
else:
    methods.add("__div__")
    methods.add("__nonzero__")
MAGIC_METHODS = frozenset(methods)
del methods

def _build_magic_dispatcher(method):
    def inner(self, *args, **kwargs):
        return self.__dict__[method](*args, **kwargs)
    inner.__name__ = method
    return inner


class stub(object):
    _classes_cache = {}

    def __new__(cls, **kwargs):
        magic_methods_present = MAGIC_METHODS.intersection(kwargs)
        if magic_methods_present not in cls._classes_cache:
            attrs = dict(
                (method, _build_magic_dispatcher(method))
                for method in magic_methods_present
            )
            attrs["__module__"] = cls.__module__
            cls._classes_cache[magic_methods_present] = type("stub",
(cls,), attrs)
        new_cls = cls._classes_cache[magic_methods_present]
        return super(stub, new_cls).__new__(new_cls, **kwargs)

    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)


> The inner method simply looks up an attribute with the same name, and
> calls it as a function with whatever args and kwargs it gets.
>
>
> Does this help?
>
>
>
> --
> Steven
> --
> http://mail.python.org/mailman/listinfo/python-list
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20130114/22d89b7f/attachment.html>


More information about the Python-list mailing list