2011-06-01 46 views
20

這是Python中的一個很好的練習(從Active State Recipes -- Public Decorator)?使用裝飾器向__all__添加名稱是一種好的做法嗎?

import sys 

def public(f): 
    """Use a decorator to avoid retyping function/class names. 

    * Based on an idea by Duncan Booth: 
    http://groups.google.com/group/comp.lang.python/msg/11cbb03e09611b8a 
    * Improved via a suggestion by Dave Angel: 
    http://groups.google.com/group/comp.lang.python/msg/3d400fb22d8a42e1 
    """ 
    all = sys.modules[f.__module__].__dict__.setdefault('__all__', []) 
    if f.__name__ not in all: # Prevent duplicates if run from an IDE. 
     all.append(f.__name__) 
    return f 

public(public) # Emulate decorating ourself 

總的想法是定義一個裝飾,需要一個功能或 類,並增加了它的名字到當前模塊的__all__

+2

修正了標題,正如有些人指出的那樣 – 2011-06-01 18:57:42

+0

雖然這看起來不錯,但我發現它混淆了我的IDE(PyCharm 2016.1.4),它大部分都會破壞目的。如果有足夠的IDE支持,我會使用它。 – 2016-07-13 20:22:25

+0

獲得這個裝飾器100%防彈似乎更難:看到[Python bug#26632](https://bugs.python.org/issue26632)和['atpublic'模塊](https:// pypi。 python.org/pypi/atpublic)在那裏提到。 – kostix 2016-12-10 09:25:29

回答

6

是的,這是一個很好的做法。這個裝飾器允許你在函數或類定義中表達你的意圖,而不是直接在之後。這使您的代碼更具可讀性。

@public 
def foo(): 
    pass 

@public 
class bar(): 
    pass 

class helper(): # not part of the modules public interface! 
    pass 

注:helper仍然是由modulename.helper一個模塊的用戶訪問。它只是沒有與from modulename import *進口。

+7

我不一定會說這是一個很好的做法。在模塊開頭明確定義'__all__'的好處是,任何人(可能你)都可以很容易地通過'import *'確定輸出的內容,模塊的公共API是什麼。使用公共裝飾器使得這變得更加困難。但是,如果您使用裝飾器,則可以在查看模塊的成員時判斷它是否在'__all__'中。所以兩者各有利弊。 – darkfeline 2013-03-19 23:58:37

+0

Everything darkfeline said plus - 它使用樸素代碼標記器打破IDE的智能感知/代碼完成。 – synthesizerpatel 2013-11-30 05:06:04

1

這不會自動將名稱添加到__all__,它只是允許您通過用@public裝飾它來爲所有人添加功能。對我來說似乎是一個不錯的主意。

+0

通過自動,我基本上意味着不用在列表中明確輸入名稱 – 2011-06-01 18:57:10

+1

是的。 (另外11個字符) – LaC 2011-06-01 19:18:19

1

我認爲這個問題有點主觀,但我喜歡這個主意。我通常在我的模塊中使用__all__,但我有時會忘記添加一個新功能,我打算將其作爲模塊公共接口的一部分。由於我通常通過名稱而不是通配符導入模塊,因此直到我的團隊中的其他人(使用通配符語法導入模塊的整個公共接口)開始抱怨爲止,我才注意到錯誤。

注意:問題的標題是誤導的,因爲其他人已經注意到了答案。

17

更習慣的方法在Python做,這是通過用下劃線開始他們的名字,以紀念私有函數私有:

def public(x): 
     ... 


def _private_helper(y): 
    ... 

更多的人會熟悉這種風格(也由支持語言:_private_helper即使不使用__all__也不會被導出),而不是使用您的public修飾器。

+2

這似乎沒有解決裝飾者解決的問題:將__all__中的名稱保持爲最新。 – 2011-06-01 20:18:10

+4

@EdL這是因爲如果你一直使用下劃線作爲「私人」事物並且沒有公共事物的下劃線,那麼你根本不需要'__all__' – 2013-05-15 08:02:53

+1

@TobiasKienzler是不是將任何導入的模塊導出?你可能仍然想阻止這些。 – 2015-10-23 08:08:16

相關問題