Python – как я могу динамически удалить метод из класса – т. Е. Напротив setattr

Я не знаю, есть ли у меня хороший дизайн здесь, но у меня есть класс, который получен из unittest.TestCase и способ, которым я его настроил, мой код будет динамически вводить кучу методов test_* в класс перед вызовом unittest, чтобы пройти через него. Для этого я использую setattr . Это работает хорошо, но теперь у меня есть ситуация, когда я хочу удалить методы, которые я ранее вводил, и вводить новый набор методов. Как удалить все методы в классе, чьи имена соответствуют шаблону test_* ?

Это называется delattr и документируется здесь .

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

delattr() – это то, что вы хотите. vars() через vars() класса и проверьте имена атрибутов, начиная с "test_" . Например,

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

Я бы посоветовал использовать dir() , так как это также покажет вам имена из ваших родительских классов, поэтому не все имена, которые вы получаете из dir() могут быть определены в таргетинге класса.

В качестве дополнения к предыдущим ответам: если повторно удаляемый метод будет удален, вам придется удалить подклассы и методы родительского класса:

 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 

(Или используйте delattr из ответа @ BrenBarn)