Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to repair a clobbered method of a Python object?

In an interactive Python session, I sometimes do dumb things like

plot.ylimits = (0,100)

where plot is an instance of some Plot class, and ylimits is a method for it. I should have tapped in this:

plot.ylimits(0,100)

The way Python works, the plot object now has a new member named ylimits which hold a tuple as its value, and the method, the executable subroutine originally provided by the Plot class, which used to be invoked with ylimits(...) is gone. Maybe somewhere in my mind I'm thinking ylimits is a property, and assigning to it invokes some hidden setter method, as is done in some other languages.

How can I get back that method? Just how can a repair my plot object, while staying in the interactive session where I have many other variables, functions, etc. in use?

I find that reload(theplotmodule) doesn't do the job. I have ruined a specific instance of Plot; refreshing the definition of the Plot class and other stuff doesn't help.

I'm using Python 2.7

like image 893
DarenW Avatar asked Feb 17 '23 20:02

DarenW


2 Answers

A simple way is to do del plot.ylimits. In general, methods are defined on the class, not the instance. Python just looks attributes up every time you try to access them, and when it doesn't find them on the instance, it goes to the class. When you did plot.ylimits=(0,100), you created a new instance attribute, so Python stops there and doesn't look for the class attribute, even though it still exists. del plot.ylimits will delete the instance attribute, and now plot.ylimits will again access the method by looking it up on the class.

Note, though, that this only works when the thing you overwrote was originally on the class, not the instance. If you actually have data stored on the instance, and you overwrite it, it's gone forever.

like image 57
BrenBarn Avatar answered Feb 20 '23 08:02

BrenBarn


Ah, BrenBarn's answer is so much better than mine, but still...

Assign it back using the method from plots class(assuming you didn't keep bound method) and converting it to MethodType, like this:

class C:

    def f(self):
        print "hello!"

c = C()

c.f = "opps!"

import types
c.f = types.MethodType(C.f, c)

c.f()
like image 42
kerim Avatar answered Feb 20 '23 10:02

kerim