2010-04-09 82 views
1

在我問這個問題之前,請注意:我希望這是爲了調試目的。我知道這會是一些不好的黑魔法,但我想在調試時使用它,以便更容易地識別我的對象。獲取創建對象的屬性名稱

就是這樣。我從A類的一些對象,創建一些B實例作爲屬性:

class A(object): 
    def __init__(self) 
     self.vanilla_b = B() 
     self.chocolate_b = B() 

class B(object): 
    def __init__(self): 
     # ... 

我想的是,在B.__init__,它會找出"vanilla_b"或任何屬性名稱,這給,然後把那個作爲.name屬性爲此特定的B

然後在調試的時候我看到一些B對象漂浮在附近,我可以知道它是哪一個。

有沒有辦法做到這一點?

回答

2

您可以使用sys._getframe獲取B()的行號,然後您可以使用inspect.getsourcelines獲取實際的代碼行。從那裏,你可以解析的代碼行去哪個B()被分配的東西:

import sys 
import inspect 

class A(object): 
    def __init__(self): 
     self.vanilla_b = B() 
     self.chocolate_b = B() 

class B(object): 
    def __init__(self): 
     line_num = sys._getframe().f_back.f_lineno 
     lines = inspect.getsourcelines(sys.modules[__name__])[0] 
     line = lines[line_num - 1] 
     attr = line.split("=")[0].split(".")[1].strip() 
     print "B() is being assigned to", attr 

A() 

如果你把上面的代碼放到一個python腳本並運行它,然後它會打印

B() is being assigned to vanilla_b 
B() is being assigned to chocolate_b 

但是,這不適用於Python命令提示符,因爲__main__是內置模塊,因此檢查模塊無法檢索其源代碼行。所以你可能想把它包裝在try/catch塊或者什麼東西,以防你的代碼從任何內置模塊被調用。

爲了記錄,這可能是一個壞主意,但是你說你知道這不是一個好習慣,而只是爲了調試而做的,所以希望你能夠使用這種明智地欺騙。

+0

啊,將文件名綁定到代碼上太麻煩了。 – 2010-04-09 15:43:43

+0

@ cool-RR:我編輯了使用inspect模塊的答案,以便您不必鍵入文件名。 – 2010-04-09 15:48:11

0

這可能不是你要找的答案,但也許你可以做沿着這樣的:

class A(object): 
    def __init__(self): 
     attrs = ('vanilla_b', 'chocolate_b') 

     for attr in attrs: 
      instance = B() 
      setattr(self, attr, instance) 
      instance.name = attr 

嘗試包裝這種行爲在一定超,你會好到哪裏去。

+0

有點問題,我想創建每個'B'有不同的參數。如果沒有足夠好的魔法,我可能會採用這種方法。 – 2010-04-09 15:45:16

+0

好的。爲了解決這個問題,你可以將屬性實例化爲一個字典(key = name,value = object)。 – 2010-04-09 15:50:59

0

如果你有代碼控制,那麼最好是簡單地依靠一些黑魔法,做

class A(object): 
    def __init__(self) 
     self.vanilla_b = B(name="vanilla_b") 
     self.chocolate_b = B(name="chocolate_b") 

否則,你可以使用檢查模塊去通過本地人和自我prev框架和做一些vodoo。

+0

我知道這種方法,謝謝。我的整個問題是,「我該如何做伏都教?」 – 2010-04-09 15:39:42

-1

不是很神奇,但:

class A(object): 
    def __init__(self) 
     self.vanilla_b = B(self) 
     self.chocolate_b = B(self) 

和:

class B(object): 
    def __init__(self, a): 
     for i in dir(a): 
      if getattr(a, i) == self: 
       pass # store it somewhere now 

編輯:對不起,這是不行的。 B. init在設置A中的引用之前執行。

+0

不好,'B'對象不應該獲得對'A'的引用。 – 2010-04-09 15:42:51