Nie wiem, czy mam tutaj dobry projekt, ale mam klasę wywodzącą się z unittest.TestCase i sposób, w jaki ja Po skonfigurowaniu, mój kod będzie dynamicznie wprowadzał do klasy kilka metod test_*
przed wywołaniem unittest, aby je uruchomić. Używam do tego setattr
. To działa dobrze, ale teraz mam sytuację, w której chcę usunąć metody wcześniej wstrzyknięte i wstrzyknąć nowy zestaw metod. Jak mogę usunąć wszystkie metody w klasie, której nazwy pasują do wzorca test_*
?Python - jak mogę dynamicznie usunąć metodę z klasy - tj. Przeciwieństwo setattr
5
A
Odpowiedz
14
Nazywa się delattr
i jest dokumentowany here.
3
>>> class Foo:
def func(self):
pass
...
>>> dir(Foo)
['__doc__', '__module__', 'func']
>>> del Foo.func
>>> dir(Foo)
['__doc__', '__module__']
1
delattr()
jest to, co chcesz. Przeprowadź pętlę przez klasę vars()
i przetestuj nazwy atrybutów zaczynające się od "test_"
. Np
@classmethod
def remove_test_methods(cls):
for name in list(vars(cls)):
if name.startswith("test_") and callable(getattr(cls, name)):
delattr(cls, name)
Radzę przed użyciem dir()
, jak będzie to pokazać nazwy z klas nadrzędnych, tak więc nie wszystkie nazwy można uzyskać z dir()
może zdefiniowane na klasie jesteś kierowania.
0
Jako dodatek do poprzednich odpowiedzi: Jeśli metoda ma zostać usunięty zostaje ponownie wprowadzone, trzeba by usunąć metod klasy i podklasy rodzicem, zarówno:
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
(lub skorzystać z delattr
Odpowiedź @ BrenBarn)
Czy też "del" nie działa? –
@JasonSperske: Nie, jeśli musisz usunąć atrybut, którego nazwa została obliczona programowo. Możesz użyć tylko 'del', aby usunąć nazwę, którą możesz dosłownie wpisać w kodzie źródłowym. – BrenBarn
@JasonSperske - tytuł mówi "przeciwieństwo setattr", co oznacza, że OP zna nazwę metody jako ciąg ... – mgilson