manually implementing staticmethod()?

7

7stud

Hi,

Can someone show me how to manually implement staticmethod()? Here is
my latest attempt:
----------------
def smethod(func):

def newFunc():
pass

def newGet():
print "new get"

newFunc.__get__ = newGet

return newFunc

class Test(object):

def show(msg):
print msg
show = smethod(show)


Test.show("hello")
--------------
....but I keep getting the error:

TypeError: unbound method newFunc() must be called with Test instance
as first argument (got str instance instead)

I think I need to intercept the function's __get__() method in order
to block creation of the method object, which requires that the
unbound method call provide an instance.
 
A

Alex Martelli

7stud said:
Hi,

Can someone show me how to manually implement staticmethod()? Here is

Simplest way:

class smethod(object):
def __init__(self, f): self.f=f
def __call__(self, *a, **k): return self.f(*a, **k)


Alex
 
7

7stud

Hi,

Thanks for the responses.



I was using that article to help me. My problem was I was trying to
implement smeth() as a function rather than a class. I hacked around
some more, and I came up with the following before peeking at this
thread for the answer:

class smeth(object):
def __init__(self, func):
self.func = func

def __getattribute__(self, name):
print "smeth -- getattribute"
return super(smeth, self).__getattribute__(name)

def __get__(self, inst, cls=None):
print "smeth get"
return self.func

class Test(object):
def __getattribute__(self, name):
print "Test - gettattribute"
return super(Test, self).__getattribute__(name)
def f():
print "executing f()"
return 10
f = smeth(f)

print Test.f #displays function obj not unbound method obj!
Test.f()

However, my code does not seem to obey this description in the How-To
Guide to Descriptors:

---------
Alternatively, it is more common for a descriptor to be invoked
automatically upon attribute access. For example, obj.d looks up d in
the dictionary of obj. If d defines the method __get__, then
d.__get__(obj) is invoked according to the precedence rules listed
below.***The details of invocation depend on whether obj is an object
or a class***.
....
For objects, the machinery is in object.__getattribute__ which
transforms b.x into type(b).__dict__['x'].__get__(b, type(b)).
....
For classes, the machinery is in type.__getattribute__ which
transforms B.x into B.__dict__['x'].__get__(None, B).
---------

When I examine the output from my code, Test.f does not call
Test.__getattribute__(), instead it calls smeth.__get__() directly.
Yet that last sentence from the How-To Guide to Descriptors seems to
say that Test.__getattribute__() should be called first.


I'm using python 2.3.5.

Simplest way:

class smethod(object):
def __init__(self, f): self.f=f
def __call__(self, *a, **k): return self.f(*a, **k)

Alex

Interesting. That looks like a functor to me. Thanks. I notice that
__get__() overrides __call__().
 
A

Alex Martelli

7stud said:
I'm using python 2.3.5.



Interesting. That looks like a functor to me. Thanks. I notice that
__get__() overrides __call__().

Not sure what you mean by "overrides" in this context. Accessing an
attribute that's a descriptor in the class invokes __get__ (having a
__get__ is the definition of "being a descriptor"); here, we have no
conceivable use for __get__, thus we simply omit it, so that instances
of smethod aren't descriptors and accessing them as attributes does
nothing special whatsoever. __call__ operates when a call is made, an
operation that is completely separate (and temporally later than) the
"accessing as an attribute" (or whatever other "accessing").

Not sure what you mean by "a functor" (a terminology that's alien to
Python, though I'm sure other languages embrace it whole-heartedly). If
you mean "a callable that's not a function", why, sure, an instance of
smethod is callable, and it's not a function. Of course, there are many
other ways of building objects that are callable and aren't functions:

def smethod(f):
def __new__(cls, *a, **k): return f(*a, **k)
return type(f.__name__,(),dict(__new__=__new__))

Is this "a functor", too? I don't really know, nor care -- it's just a
somewhat more intricate way to make callables that aren't functions.


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,775
Messages
2,569,601
Members
45,182
Latest member
alexanderrm

Latest Threads

Top