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))