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)但能分开显示?
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>>>> import inspect<br>>>> inspect.getmembers(A, inspect.isfunction)<br>[('aa', <function __main__.A.dd>),<br> ('d', <function __main__.A.d>),<br> ('dd', <function __main__.A.dd>)]<br><br>>>> inspect.getmembers(A, lambda x: not callable(x))<br>[('__dict__',<br> mappingproxy({'__dict__': <attribute '__dict__' of 'A' objects>,<br> '__doc__': None,<br> '__module__': '__main__',<br> '__weakref__': <attribute '__weakref__' of 'A' objects>,<br> 'a': '这是属性',<br> 'aa': <function __main__.A.dd>,<br> 'd': <function __main__.A.d>,<br> 'dd': <function __main__.A.dd>})),<br> ('__doc__', None),<br> ('__module__', '__main__'),<br> ('__weakref__', <attribute '__weakref__' of 'A' objects>),<br> ('a', '这是属性')]<br>
非常感谢各位!
pdir 内部也是调用 inspect。
谢谢!
nice
pdir2 不错,感谢一下 XYxe。也感谢一下提问者,我也在有过同样的疑问,比如 pathlib 里的 Path 不知道哪个是属性、哪个是方法……

