【问题标题】:How to test if a class attribute is an instance method如何测试类属性是否为实例方法
【发布时间】:2009-07-07 09:23:23
【问题描述】:

在 Python 中,我需要高效且通用地测试类的属性是否为实例方法。调用的输入将是被检查属性的名称(一个字符串)和一个对象。

无论属性是否为实例方法,hasattr 都会返回 true。

有什么建议吗?


例如:

class Test(object):
    testdata = 123

    def testmethod(self):
        pass

test = Test()
print ismethod(test, 'testdata') # Should return false
print ismethod(test, 'testmethod') # Should return true

【问题讨论】:

  • 你确定你需要知道它是一种方法吗?你真的很想知道你能不能打电话吗?这些不一定是同一件事(尽管它们当然经常是)。
  • 看源码有什么问题?这是 Python——你有源代码——你为什么不能简单地阅读它?
  • 阅读源代码没有任何帮助-大概他正在编写一些需要在运行时知道答案的代码。例如,可能遍历对象的所有属性。

标签: python methods attributes instance


【解决方案1】:
def hasmethod(obj, name):
    return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType

【讨论】:

  • 请注意“getattr”可能涉及代码执行。这个答案是获取 obj 的“name”属性的值,然后测试该值的类型。如果使用 Python 3,请导入检查,并将“getattr”替换为“inspect.getattr_static”,从而避免该评估。 docs.python.org/3.3/library/…
  • 这仅在您只是想检查该方法是否为实例方法时才有效,它无法识别该方法是否绑定到当前实例。
【解决方案2】:

您可以使用inspect 模块:

class A(object):
    def method_name(self):
        pass


import inspect

print inspect.ismethod(getattr(A, 'method_name')) # prints True
a = A()
print inspect.ismethod(getattr(a, 'method_name')) # prints True

【讨论】:

  • 该问题要求一个函数,该函数将为您的示例大写 A 返回 False 并为您的示例小写 'a' 返回 true 也就是说,问题是,从对象属性中,如何我们判断它是否可调用并且它是实例的属性,不是类属性(静态成员函数)。
【解决方案3】:
import types

print isinstance(getattr(your_object, "your_attribute"), types.MethodType)

【讨论】:

    【解决方案4】:

    此函数检查属性是否存在,然后检查该属性是否为使用inspect 模块的方法。

    import inspect
    
    def ismethod(obj, name):
        if hasattr(obj, name):
            if inspect.ismethod(getattr(obj, name)):
                return True
        return False
    
    class Foo:
        x = 0
        def bar(self):
            pass
    
    foo = Foo()
    print ismethod(foo, "spam")
    print ismethod(foo, "x")
    print ismethod(foo, "bar")
    

    【讨论】:

      【解决方案5】:

      请注意,@classmethod-decorated 函数将通过其他答案中的所有测试。您希望这些被视为“实例方法”吗?也许这只是语义,但根据定义,它们对类进行操作,而不是生成的实例。我不确定 hasmethod2(我提出的解决方案)失败的情况,但至少它可以警惕类方法:

      
      import inspect
      import types
      
      def hasmethod(obj, name):
          return hasattr(obj, name) and type(getattr(obj, name)) == types.MethodType
      
      def hasmethod2(obj, name):
          try:
              attr = getattr(obj, name)
              return not inspect.isclass(attr.__self__)
          except AttributeError:
              return False
      
      class Test(object):
          testdata = 123
      
          def testmethod(self):
              pass
      
          @classmethod
          def testmethod2(cls):
              pass
      
      # Returns True. This may be undesired depending on your definition of 'instance method'
      hasmethod(Test(), 'testmethod2')
       
      # Returns False
      hasmethod2(Test(), 'testmethod2')
      

      之所以有效,是因为__self__ 绑定到主调用参数(类方法的类实例、普通属性的对象实例、模块或各种内置函数的任何内容)。因此,检查__self__ 的存在和__self__ 不是一个类分别排除了非函数属性和类方法。

      【讨论】:

        猜你喜欢
        • 2019-09-23
        • 1970-01-01
        • 1970-01-01
        • 2012-04-29
        • 2013-03-16
        • 2014-05-05
        • 1970-01-01
        • 2014-03-31
        • 2022-12-10
        相关资源
        最近更新 更多