2012-03-24 62 views
0

我想回到創建迭代器的函數。在我的情況下,我有興趣獲得原始文檔字符串。如何獲得已創建迭代器的函數發生器的引用?

例子:

def my_generator(): 
    """this is my generator""" 
    for x in (1,2,3): 
     yield x 


my_iter = my_generator() 

# in another part of my code where I Only have access to the iterator 
# no access to the generator function "my_generator" 
assert my_iter.????.__doc__ == "this is my generator" 
+0

你知道了'dir'功能,對不對? – Marcin 2012-03-24 16:10:22

回答

2

感覺哈克,但一個方法是在文檔字符串獲得將通過co_consts

localhost-2:coding $ cat mod1.py 
def my_generator(): 
    """this is my generator""" 
    for x in (1,2,3): 
     yield x 

it = my_generator() 

localhost-2:coding $ python 
Python 2.7.2 (v2.7.2:8527427914a2, Jun 11 2011, 15:22:34) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mod1 
>>> mod1.it.__doc__ 
>>> mod1.it.gi_code.co_consts[0] 
'this is my generator' 
>>> z = mod1.my_generator() 
>>> z.__doc__ 
>>> z.gi_code.co_consts[0] 
'this is my generator' 

我會更傾向於找出一些裝飾,以適用於發電機的功能,以確保文檔字符串保持不變。

如果你需要的功能本身,怎麼樣:

>>> import mod1 
>>> z = mod1.my_generator() 
>>> z.__doc__ 
>>> z.gi_frame.f_globals[z.__name__] 
<function my_generator at 0x1004b7cf8> 
>>> z.gi_frame.f_globals[z.__name__] is mod1.my_generator 
True 
>>> z.gi_frame.f_globals[z.__name__].__doc__ 
'this is my generator' 

,但我不作任何承諾,這適用於任何情況下..

+0

這並不能解決獲得對函數的引用的更一般的問題,但它解決了我的問題,所以我接受它。我不能使用裝飾器,因爲這個生成器函數在「客戶端代碼」上。 – schettino72 2012-03-24 16:38:09

+0

不幸的是,你的解決方案gi_frame.f_globals不適用於我的測試用例。實際上,在我發佈一個問題之前,我曾嘗試過:'z.gi_frame.f_back.f_locals [z .__ name __]',但由於某種原因,z.gi_frame.f_back始終爲None。 – schettino72 2012-03-24 17:05:33

1

什麼locals()[my_iter.__name__].__doc__

+1

我更新了問題。當然,生成器函數不在本地命名空間中。否則它會太容易:D – schettino72 2012-03-24 16:03:02