Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: code explanation

Reply
Thread Tools

Re: code explanation

 
 
Steven D'Aprano
Guest
Posts: n/a
 
      01-15-2013
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.

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
 
Reply With Quote
 
 
 
 
Rodrick Brown
Guest
Posts: n/a
 
      01-15-2013
On Mon, Jan 14, 2013 at 11:38 PM, Steven D'Aprano <
http://www.velocityreviews.com/forums/(E-Mail Removed)> 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
>


 
Reply With Quote
 
 
 
 
Ian Kelly
Guest
Posts: n/a
 
      01-15-2013
On Mon, Jan 14, 2013 at 9:51 PM, Rodrick Brown <(E-Mail Removed)> wrote:
> 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 stub class is called with keyword arguments where the keys are the
names of Python "magic methods" and the values are functions. When
called, it builds a new subclass of itself populated with a
corresponding set of methods, each of which is built by
_build_magic_dispatcher; these look up the method with the same name
in the instance dictionary and delegate the call to whatever they
find. For some reason that eludes me, the generated methods appear to
discard the "self" argument in the process. After the subclass is
generated, it constructs and returns an instance of the subclass, and
then when the __init__ method is called it simply populates the
instance dictionary with the functions that were passed in.

The purpose of this appears to be to construct objects with magic
methods that are defined on the object itself rather than on the
class. Normally, when Python calls a magic method it doesn't look in
the instance dictionary at all and only looks in the class dictionary.
The subclasses of "stub" side-step that by having the desired magic
methods on the class delegate calls to the instance.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Explanation on some code Michael Albers Ruby 5 12-01-2008 06:18 PM
looking for explanation of bind2nd() source code responsible C++ 4 08-05-2008 03:51 PM
Code explanation requeted Neville Franks Ruby 4 02-06-2007 06:58 PM
JCP code- can anybody gve explanation uthra Java 1 11-10-2006 09:04 PM
Explanation of code needed Phil Thompson Javascript 4 03-22-2005 05:55 PM



Advertisments