W funkcji __getattr__()
, jeśli zmienna, do której odnosi się odwołanie, nie zostanie znaleziona, spowoduje to błąd. Jak mogę sprawdzić, czy zmienna lub metoda istnieje jako część obiektu?
import string
import logging
class Dynamo:
def __init__(self,x):
print "In Init def"
self.x=x
def __repr__(self):
print self.x
def __str__(self):
print self.x
def __int__(self):
print "In Init def"
def __getattr__(self, key):
print "In getattr"
if key == 'color':
return 'PapayaWhip'
else:
raise AttributeError
dyn = Dynamo('1')
print dyn.color
dyn.color = 'LemonChiffon'
print dyn.color
dyn.__int__()
dyn.mymethod() //How to check whether this exist or not
Łatwiej jest prosić o przebaczenie niż o pozwolenie.
Nie sprawdzaj, czy metoda istnieje. Nie trać ani jednej linii kodu na „sprawdzanie”
try: dyn.mymethod() # How to check whether this exists or not # Method exists and was used. except AttributeError: # Method does not exist; What now?
źródło
dyn.mymethod()
podniesieAttributeError
sam.Sprawdź, czy klasa ma taką metodę?
hasattr(Dynamo, key) and callable(getattr(Dynamo, key))
lub
hasattr(Dynamo, 'mymethod') and callable(getattr(Dynamo, 'mymethod'))
Możesz użyć
self.__class__
zamiastDynamo
źródło
None
nie jest wywoływalne, więc możesz to zrobićcallable(getattr(Dynamo, 'mymethod', None))
. Użyłem tej odpowiedzi, ponieważ moja super (). Mymethod () mogła rzucićAttributeError
def getattr(object, name, default=None):
podejrzewany, że nie jest dokładny, ponieważ gdyby tak było, spodziewałbym się, że podanie None jako trzeciego parametru nie zmieni zachowania funkcji.help(getattr)
mówi: „Gdy podano domyślny argument, jest on zwracany, gdy atrybut nie istnieje; bez niego zgłaszany jest wyjątek w takim przypadku”. - (i rzeczywiście możesz sprawdzić, czy getattr zgłasza wyjątek, jeśli brakuje atrybutu), więc wyraźnie, niezależnie od PyCharm, jest źle.if hasattr(self, "work") and callable(self.work)
. Sprawdza, czy instancja ma atrybut pracy (może to być zmienna lub funkcja), a następnie sprawdza, czy można ją wywołać (co oznacza, że jest to funkcja).Możesz spróbować użyć modułu „inspect”:
import inspect def is_method(obj, name): return hasattr(obj, name) and inspect.ismethod(getattr(obj, name)) is_method(dyn, 'mymethod')
źródło
Używam poniżej funkcji użytkowej. Działa na lambdzie, metodach klas oraz metodach instancji.
Metoda użytkowa
def has_method(o, name): return callable(getattr(o, name, None))
Przykładowe użycie
Zdefiniujmy klasę testową
class MyTest: b = 'hello' f = lambda x: x @classmethod def fs(): pass def fi(self): pass
Teraz możesz spróbować,
>>> a = MyTest() >>> has_method(a, 'b') False >>> has_method(a, 'f') True >>> has_method(a, 'fs') True >>> has_method(a, 'fi') True >>> has_method(a, 'not_exist') False
źródło
try
instrukcji) i sprawdza, gdy element członkowski jest rzeczywistą funkcją. świetny udział!Co powiesz na to, żeby to sprawdzić
dyn.__dict__
?try: method = dyn.__dict__['mymethod'] except KeyError: print "mymethod not in dyn"
źródło
Może w ten sposób, zakładając, że wszystkie metody można wywołać
app = App(root) # some object call app att = dir(app) #get attr of the object att #['doc', 'init', 'module', 'button', 'hi_there', 'say_hi'] for i in att: if callable(getattr(app, i)): print 'callable:', i else: print 'not callable:', i
źródło
Jeśli twoja metoda jest poza klasą i nie chcesz jej uruchamiać i zgłaszać wyjątek, jeśli nie istnieje:
'mymethod' in globals()
źródło
Myślę, że powinieneś spojrzeć na
inspect
opakowanie. Pozwala na „zawinięcie” niektórych rzeczy. Kiedy używaszdir
metody, wyświetla ona również listę wbudowanych metod, metod dziedziczonych i wszystkich innych atrybutów umożliwiających kolizje, np .:class One(object): def f_one(self): return 'class one' class Two(One): def f_two(self): return 'class two' if __name__ == '__main__': print dir(Two)
Tablica, z której otrzymujesz,
dir(Two)
zawiera zarównof_one
i, jak if_two
wiele wbudowanych elementów. Dzięki temuinspect
możesz to zrobić:class One(object): def f_one(self): return 'class one' class Two(One): def f_two(self): return 'class two' if __name__ == '__main__': import inspect def testForFunc(func_name): ## Only list attributes that are methods for name, _ in inspect.getmembers(Two, inspect.ismethod): if name == func_name: return True return False print testForFunc('f_two')
W tych przykładach nadal wymieniono obie metody z dwóch klas, ale jeśli chcesz ograniczyć inspekcję tylko do funkcji w określonej klasie, wymaga to nieco więcej pracy, ale jest to absolutnie możliwe.
źródło