How do I extend a class that I never instantiate myself?
Chris Angelico
rosuav at gmail.com
Sun Oct 11 02:32:09 EDT 2015
On Sun, Oct 11, 2015 at 4:53 PM, dieter <dieter at handshake.de> wrote:
> Otherwise, you can likely use a technique called "monkey patching".
> This is dynamically changing code at startup time.
> In your case, it could look like:
>
> from ... import Node
>
> def new_method(self, ...):
> ...
>
> Node.new_method = new_method
>
> From that moment on, the "Node" class has a new method "new_method".
And if you're going to do this for a good number of methods, I'd
recommend something like this:
def monkeypatch(cls):
def deco(func):
setattr(cls, func.__name__, func)
return func
return deco
@monkeypatch(Node)
def new_method(self, ...):
...
@monkeypatch(Node)
def another_new_method(self, ...):
...
@monkeypatch(Node)
def yet_another(self, ...):
...
@monkeypatch(Node)
def and_another(self, ...):
...
If you REALLY want to look like Ruby, you could actually do something
rather sneaky. When a decorator is called, the name has yet to be
bound; conceptually, it's like defining the function/class and then
using "x = deco(x)" at the end, but you can actually access the
previous use of that name. So check this out:
# -- cut --
class Foo:
def old_method(self):
print("Old method.")
print("Before we begin patching, Foo is %x." % id(Foo))
def monkeypatch(cls):
# NOTE: Needs to be able to find its own globals, so you
# can't use this inside a function or import it from another
# module. Play with sys._getframe if you want to.
old = globals()[cls.__name__]
print("Inside monkeypatch, old is %x, and cls is %x." % (id(old), id(cls)))
for attr in dir(cls):
# Don't override dunders. TODO: Figure out if they were
# set here, and if so, *do* override.
if attr.startswith("__") and attr.endswith("__"): continue
setattr(old, attr, getattr(cls, attr))
return old
@monkeypatch
class Foo:
def new_method(self):
print("New method!")
print("After patching, Foo is %x." % id(Foo))
f = Foo()
f.old_method()
f.new_method()
# -- cut --
However, don't blame me if other programmers chase you down with
torches and pitchforks.
ChrisA
More information about the Python-list
mailing list