你可以测试属性的类型:
from types import MethodType
from pprint import pprint
class A(object):
def __init__(self) -> None:
self._field = 3
self._callable_field = lambda x: x
def my_method(self):
pass
@classmethod
def my_static_method(cls):
pass
def __str__(self) -> str:
return repr(self)
A.another_method = lambda self: None
a = A()
pprint([(d, type(getattr(a,d)) is MethodType) for d in dir(a)])
打印
[('__class__', False),
('__delattr__', False),
('__dict__', False),
('__dir__', False),
('__doc__', False),
('__eq__', False),
('__format__', False),
('__ge__', False),
('__getattribute__', False),
('__gt__', False),
('__hash__', False),
('__init__', True),
('__init_subclass__', False),
('__le__', False),
('__lt__', False),
('__module__', False),
('__ne__', False),
('__new__', False),
('__reduce__', False),
('__reduce_ex__', False),
('__repr__', False),
('__setattr__', False),
('__sizeof__', False),
('__str__', True), # <<<<<<<<<<
('__subclasshook__', False),
('__weakref__', False),
('_callable_field', False), # <<<<<<<<<<
('_field', False), # <<<<<<<<<<
('another_method', True), # <<<<<<<<<<
('my_method', True), # <<<<<<<<<<
('my_static_method', True)] # <<<<<<<<<<
请注意,对于未在类定义中明确定义的内置方法(或稍后附加,请参阅上面的 __str__ 和 another_method),这不会打印 True。另请注意,与测试 callable 不同,这实际上抓住了方法和可调用属性之间的区别。