Python中如何获取对象特定属性的字符串形式属性名?
如何通过Python对象的属性值获取对应的属性名?
嘿,这个问题我碰到过好几次——Python本身不会自动维护“属性值→属性名”的反向映射,毕竟一个值可能被多个属性甚至多个对象引用,默认存这个反而会浪费内存。不过咱们完全可以自己实现反向查找的逻辑,分几种情况给你说清楚:
1. 只找实例自己的属性(最常用场景)
就拿你给的例子来说,a是OneClass的实例,它的自定义属性(比如someval、whatIam)都存在它的__dict__字典里,键是属性名字符串,值就是对应的属性值。我们只要遍历这个字典就能反向查找:
先把你的示例代码放这方便参考:
class OneClass: def __init__(self): self.whatIam = 'I am a OneClass instance' self.whatIdo = 'Nothing really useful' def setSomeVal(self, val): self.someval = val a = OneClass() a.setSomeVal(13)
写个简单的函数就能搞定:
def find_attr_name(obj, target_value): # 遍历实例的属性字典 for attr_name, attr_val in obj.__dict__.items(): if attr_val == target_value: return attr_name # 没找到的话返回None,或者你也可以抛出异常 return None print(find_attr_name(a, 13)) # 输出: someval
这里要注意两点:
- 这个方法只找实例自己定义的属性(就是
self.xxx那种),类属性或者继承来的属性不会被包含进来。 - 如果有多个属性的值都是
13,这个函数只会返回第一个找到的。要是想找所有匹配的,改成返回列表就行。
2. 需要包含类属性的情况
如果你还想找类层面的属性(比如OneClass本身定义的属性),可以用dir(obj)先拿到所有可用的属性名,再用getattr()去取值判断:
def find_attr_name_with_class(obj, target_value): for attr_name in dir(obj): # 跳过那些双下划线开头结尾的内置属性/方法,比如__init__、__dict__ if attr_name.startswith('__') and attr_name.endswith('__'): continue try: attr_val = getattr(obj, attr_name) if attr_val == target_value: return attr_name except AttributeError: # 有些属性可能是描述符之类的,没法直接取值,直接跳过就行 continue return None
几个要注意的坑
- 值的唯一性:刚才说了,多个属性可能对应同一个值,如果你要所有匹配项,把函数里的
return attr_name改成把名字加到列表里最后返回就行。 - 性能问题:如果实例有几百上千个属性,遍历的开销会有点大,这种反向查找尽量别放在高频调用的代码里。
- 动态属性/描述符:比如用
@property定义的属性,调用getattr()会触发它的计算逻辑,可能有副作用(比如打印日志、修改其他值),用的时候要小心。
关于“属性名和值的映射是否存储在某处”
直接给结论:没有内置的存储。Python对象的属性系统是正向的——只存“属性名→属性值”的映射,反向的“值→名”完全是按需自己实现的。毕竟维护这种反向映射需要额外的内存,而且大部分场景下根本用不到,所以Python默认不提供。
内容的提问来源于stack exchange,提问作者ztl
相关产品推荐
相关产品推荐

