1

为了调试目的,我们希望获取给定对象已知的所有名称;我想要限定名称(即A.x而不是x)。下面是我们的第一次尝试:查找引用给定对象的限定名称

import gc, sys 
def find_names(obj): 
    result = [] 
    for referrer in gc.get_referrers(obj): 
     if isinstance(referrer, dict): 
      for k in referrer: 
       if referrer[k] is obj: 
        n = '???' 
        for f in ('__qualname__', '__name__'): 
         if f in referrer: 
          n = referrer[f] 
        result.append('{}.{}'.format(n, k)) 
    return ','.join(result) 

的问题是,除非容器是一个类或模块(当时__qualname____name__工作)的__dict__我找不到从容器容器自身的“名字”。我不知道为什么__class__不是实例的__dict__(是否存储在插槽中?)的一部分,但原因并不重要 - 重要的是我无法得到它。

有什么我可以做这个工作如下:

class A: 
    pass 
a = A() 
a.x = object() 
find_names(a.x) # I want this to return `a.x` rather than `???.x` 

回答

0

我想我可以通过检查对应于一个实例任何指引的引荐,并寻找其__dict__一个做与原始推荐人相同:

def find_names(obj): 
    result = [] 
    for referrer in gc.get_referrers(obj): 
     if isinstance(referrer, dict): 
      for k in referrer: 
       if referrer[k] is obj: 
        n = '???' 
        for f in ('__qualname__', '__name__'): 
         if f in referrer: 
          n = referrer[f] 
          break 
        if n == '???': 
         parents = gc.get_referrers(referrer) 
         for p in parents: 
          if getattr(p, '__dict__', None) is referrer: 
           n = '<instance of class ' + p.__class__.__name__ + '>' 
        result.append(str(n) + '.' + str(k)) 
    return '\n'.join(sorted(result))