简体   繁体   English

如何检查Python中是否存在方法?

[英]How to check whether a method exists in Python?

In the function __getattr__() , if a referred variable is not found then it gives an error.在函数__getattr__() ,如果未找到引用的变量,则会出现错误。 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您可以使用self.__class__而不是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() ? getattr()之前的dir()函数怎么样?

>>> "mymethod" in dir(dyn)
True

I use below utility function.我使用以下实用程序功能。 It works on lambda, class methods as well as instance methods.它适用于 lambda、类方法以及实例方法。

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__ ?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

如果您的方法在类之外并且您不想运行它并在它不存在时引发异常:

'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.我认为您应该查看inspect包。 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, eg:当您使用dir方法时,它还会列出内置方法、继承方法和所有其他使冲突成为可能的属性,例如:

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.您从dir(Two)获得的数组包含f_onef_two以及许多内置内容。 With inspect you can do this:通过inspect您可以执行以下操作:

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.此示例仍然列出了两个类中的两种方法,但是如果您想将检查限制为仅在特定类中起作用,则需要做更多的工作,但这绝对是可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM