Python - how can I dynamically remove a method from a class — i.e. opposite of setattr

▼魔方 西西 提交于 2019-12-09 10:58:16

问题


I don't know if I have a good design here, but I have a class that is derived from unittest.TestCase and the way I have it set up, my code will dynamically inject a bunch of test_* methods into the class before invoking unittest to run through it. I use setattr for this. This has been working well, but now I have a situation in which I want to remove the methods I previously injected and inject a new set of methods. How can I remove all the methods in a class whose names match the pattern test_*?


回答1:


It's called delattr and is documented here.




回答2:


>>> class Foo:
    def func(self):
        pass
...     
>>> dir(Foo)
['__doc__', '__module__', 'func']
>>> del Foo.func
>>> dir(Foo)
['__doc__', '__module__']



回答3:


delattr() is what you want. Loop through vars() of the class and test for attribute names starting with "test_". E.g.,

@classmethod
def remove_test_methods(cls):
    for name in list(vars(cls)):
        if name.startswith("test_") and callable(getattr(cls, name)):
            delattr(cls, name)

I'd advise against using dir(), as this will show you names from your parent classes as well, so not all the names you get from dir() may defined on the class you're targeting.




回答4:


As an addition to the previous answers: If the method to be deleted is re-implemented, you'd have to delete the subclass and parent class methods, both:

class A:
    def method(self): 
        print("TestA")

class B(A):
    def method(self):
        A.method(self)
        print("TestB")

instance = B()
instance.method() # will call B.method()
del B.method
instance.method() # will now call A.method()
del A.method
instance.method() # will now raise AttributeError

(Or use delattr of @BrenBarn's answer)



来源:https://stackoverflow.com/questions/16700958/python-how-can-i-dynamically-remove-a-method-from-a-class-i-e-opposite-of

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!