How to check whether a method exists in Python?
In t开发者_C百科he function __getattr__()
, if a referred variable is not found then it gives an error. How can I check to see if a variable or method exists as part of an object?
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
Check if class has such method?
hasattr(Dynamo, key) and callable(getattr(Dynamo, key))
or
hasattr(Dynamo, 'mymethod') and callable(getattr(Dynamo, 'mymethod'))
You can use self.__class__
instead of Dynamo
It's easier to ask forgiveness than to ask permission.
Don't check to see if a method exists. Don't waste a single line of code on "checking"
try:
dyn.mymethod() # How to check whether this exists or not
# Method exists and was used.
except AttributeError:
# Method does not exist; What now?
How about dir()
function before getattr()
?
>>> "mymethod" in dir(dyn)
True
I use below utility function. It works on lambda, class methods as well as instance methods.
Utility Method
def has_method(o, name):
return callable(getattr(o, name, None))
Example Usage
Let's define test class
class MyTest:
b = 'hello'
f = lambda x: x
@classmethod
def fs():
pass
def fi(self):
pass
Now you can try,
>>> 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
You can try using 'inspect' module:
import inspect
def is_method(obj, name):
return hasattr(obj, name) and inspect.ismethod(getattr(obj, name))
is_method(dyn, 'mymethod')
How about looking it up in dyn.__dict__
?
try:
method = dyn.__dict__['mymethod']
except KeyError:
print "mymethod not in dyn"
Maybe like this, assuming all method is callable
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
If your method is outside of a class and you don't want to run it and raise an exception if it doesn't exist:
'mymethod' in globals()
For the people that likes simplicity.
class ClassName:
def function_name(self):
return
class_name = ClassName()
print(dir(class_name))
# ['__init__', .... ,'function_name']
answer = 'function_name' in dir(class_name)
print("is'function_name' in class ? >> {answer}")
# is 'function_name' in class ? >> True
I think you should look at the inspect
package. It allows you to 'wrap' some of the things. When you use the dir
method it also list built in methods, inherited methods and all other attributes making collisions possible, e.g.:
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)
The array you get from dir(Two)
contains both f_one
and f_two
and a lot of built in stuff. With inspect
you can do this:
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')
This examples still list both methods in the two classes but if you want to limit the inspection to only function in a specific class it requires a bit more work, but it is absolutely possible.
精彩评论