Python中如何区分对象属性和方法,类似dir(obj)但能分开显示?

比如有如下的类(当然只定义方法也是可以的):

class A():
	a = '这是属性'
def d(self, var):
	print('这是方法')

def dd(self):
	print('这是没有参数的方法')

aa = dd  #也算属性吧

print(dir(A))

=>[‘class’, ‘delattr’, ‘dict’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘le’, ‘lt’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘a’, ‘aa’, ‘d’, ‘dd’]

dir(obj),虽然能获得['a', 'aa', 'd', 'dd'] ,但是不能区分是方法还是属性。
有什么方法或者现成的库可以将方法和属性分开呢?
多谢您回复!


Python中如何区分对象属性和方法,类似dir(obj)但能分开显示?

8 回复
def get_obj_members(obj):
    """
    返回对象属性和方法的分类字典
    """
    members = {
        'attributes': [],
        'methods': []
    }
    
    for name in dir(obj):
        try:
            # 获取成员
            attr = getattr(obj, name)
            
            # 判断是否为可调用方法(排除内置特殊方法)
            if callable(attr):
                # 过滤掉私有方法(以__开头和结尾的通常是内置方法)
                if not (name.startswith('__') and name.endswith('__')):
                    members['methods'].append(name)
            else:
                # 非可调用对象视为属性
                members['attributes'].append(name)
                
        except (AttributeError, Exception):
            # 跳过无法访问的成员
            continue
    
    return members

# 使用示例
class MyClass:
    def __init__(self):
        self.value = 42
        self.name = "test"
    
    def get_value(self):
        return self.value
    
    def _private_method(self):
        pass

obj = MyClass()
result = get_obj_members(obj)

print("属性:", result['attributes'])
print("方法:", result['methods'])

这个函数通过callable()判断成员是否可调用来区分属性和方法。它会返回一个包含两个列表的字典:attributes(属性)和methods(方法)。注意它排除了Python内置的特殊方法(如__init__),但你可以根据需要调整过滤条件。

如果你想要更详细的区分(比如类方法、静态方法、实例方法),可以用inspect模块:

import inspect

def detailed_members(obj):
    details = {
        'attributes': [],
        'instance_methods': [],
        'class_methods': [],
        'static_methods': []
    }
    
    for name in dir(obj):
        try:
            attr = getattr(obj, name)
            
            if callable(attr):
                if inspect.ismethod(attr):
                    details['instance_methods'].append(name)
                elif inspect.isclassmethod(attr):
                    details['class_methods'].append(name)
                elif inspect.isfunction(attr):
                    details['static_methods'].append(name)
            else:
                details['attributes'].append(name)
                
        except:
            continue
    
    return details

callable()inspect模块就能精确区分。

Python 里方法就是可调用的属性,上面的 aa 和 dd 是完全一样的,没法区分。a 和 d 可以用 getattr 取出来在判断是不是 callable 区分。

注意一下 啊

aa应该算作 function 了。另外,inspect模块也可以用:

<br>&gt;&gt;&gt; import inspect<br>&gt;&gt;&gt; inspect.getmembers(A, inspect.isfunction)<br>[('aa', &lt;function __main__.A.dd&gt;),<br> ('d', &lt;function __main__.A.d&gt;),<br> ('dd', &lt;function __main__.A.dd&gt;)]<br>

<br>&gt;&gt;&gt; inspect.getmembers(A, lambda x: not callable(x))<br>[('__dict__',<br> mappingproxy({'__dict__': &lt;attribute '__dict__' of 'A' objects&gt;,<br> '__doc__': None,<br> '__module__': '__main__',<br> '__weakref__': &lt;attribute '__weakref__' of 'A' objects&gt;,<br> 'a': '这是属性',<br> 'aa': &lt;function __main__.A.dd&gt;,<br> 'd': &lt;function __main__.A.d&gt;,<br> 'dd': &lt;function __main__.A.dd&gt;})),<br> ('__doc__', None),<br> ('__module__', '__main__'),<br> ('__weakref__', &lt;attribute '__weakref__' of 'A' objects&gt;),<br> ('a', '这是属性')]<br>

非常感谢各位!
pdir 内部也是调用 inspect。
谢谢!

pdir2 不错,感谢一下 XYxe。也感谢一下提问者,我也在有过同样的疑问,比如 pathlib 里的 Path 不知道哪个是属性、哪个是方法……

回到顶部