Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I remove a method with delattr?

There mustn't be an error (according to the docs of Python 2.7):

class C(object):
    def __init__(self):
        self.d = {}


    def set_key(self, key, val):
        self.d[key] = val


    def get_key(self, key):
        return self.d[key]


c = C()
delattr(c, 'set_key')

However:

AttributeError: set_key

I can do delattr on a class object. Can I remove a bound function from an instance?

like image 388
sergzach Avatar asked Mar 11 '23 10:03

sergzach


2 Answers

set_key is an attribute of the class, not the instance. delattr(C, 'set_key') works as expected.

If you want the function not to be available from only the one instance, you can try c.set_key = None.

like image 178
Nick Matteo Avatar answered Mar 13 '23 00:03

Nick Matteo


I am not quite sure why Python (2.7 at least) isn't allowing bound methods to be deleted in this manner.

That said, here is one way to simulate your desired behaviour:

def delete_method(obj, method_name):
  def stub(*args, **kwargs):
    raise AttributeError("'%s' object has no attribute '%s'" % (
      obj.__class__.__name__, method_name))
  setattr(obj, method_name, stub)

c = C()
delete_method(c, 'set_key')
c.set_key('the_answer', 42)

When run, this gives

AttributeError: 'C' object has no attribute 'set_key'

Note that this technique isn't universal: for example, you won't be able to use it to remove a method from an instance of the dict class.

like image 25
NPE Avatar answered Mar 12 '23 22:03

NPE