Monkeypatching a staticmethod?

R

Roy Smith

This is kind of surprising. I'm running Python 2.7.1. I've got a class
with a staticmethod that I want to monkeypatch with a lambda:

----------------------------------
class Foo:
@staticmethod
def x():
return 1

Foo.x = lambda: 2
print Foo.x()
----------------------------------

What's weird is that it seems to remember that x is a staticmethod
despite having been patched:

Traceback (most recent call last):
File "static.py", line 8, in <module>
Foo.x()
TypeError: unbound method <lambda>() must be called with Foo instance as
first argument (got nothing instead)

What seems to work is to patch it with another staticmethod:

----------------------------------
class Foo:
@staticmethod
def x():
return 1

@staticmethod
def x():
return 2

Foo.x = x
print Foo.x()
----------------------------------

$ python static.py
2

I didn't even know you could define a staticmethod outside of a class!

I suspect this post is really just my way of admitting that while I've
used staticmethods plenty, I've never fully understood the details of
what happens when you construct them :)
 
I

Ian Kelly

This is kind of surprising. I'm running Python 2.7.1. I've got a class
with a staticmethod that I want to monkeypatch with a lambda:

----------------------------------
class Foo:
@staticmethod
def x():
return 1

Foo.x = lambda: 2
print Foo.x()
----------------------------------

What's weird is that it seems to remember that x is a staticmethod
despite having been patched:

Traceback (most recent call last):
File "static.py", line 8, in <module>
Foo.x()
TypeError: unbound method <lambda>() must be called with Foo instance as
first argument (got nothing instead)

No, if it were still a staticmethod then the call would work without
error. That error is the same that you would get in Python 2 if you
defined the function directly in the class without the staticmethod
decorator. (In Python 3 the call succeeds as long as it's made from
the class and not from an instance).
What seems to work is to patch it with another staticmethod:

----------------------------------
class Foo:
@staticmethod
def x():
return 1

@staticmethod
def x():
return 2

Foo.x = x
print Foo.x()
----------------------------------

$ python static.py
2

I didn't even know you could define a staticmethod outside of a class!

I suggest defining x as a normal function and writing the assignment
as "Foo.x = staticmethod(x)" to keep x callable from the global
namespace. Or just del it after doing the monkey patch.
 
P

Piet van Oostrum

Ian Kelly said:
I suggest defining x as a normal function and writing the assignment
as "Foo.x = staticmethod(x)" to keep x callable from the global
namespace. Or just del it after doing the monkey patch.

You can use Foo.x = staticmethod(lambda: 2)
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top