讓我們假設原來的版本是這樣的:
class BitsInteger:
"""BitsInteger docstring"""
def __init__(self, num):
pass
def singleton(cls):
return cls()
def singletonfunction(func):
return func()
@singletonfunction
def Bit():
"""A 1-bit BitField; must be enclosed in a BitStruct"""
return BitsInteger(1)
b = Bit
print("b.__doc__ :", b.__doc__)
與Python3.5運行這給輸出:
b.__doc_ : BitsInteger docstring
這可能不是你所期望的。當我們與python -i original.py
運行,我們可以看看究竟怎麼回事就在這裏:
>>> vars()
{'__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, 'b': <__main__.BitsInteger object at 0x7ff05d2ae3c8>, '__spec__': None, 'singletonfunction': <function singletonfunction at 0x7ff05d2b40d0>, 'singleton': <function singleton at 0x7ff05d30cd08>, '__cached__': None, 'BitsInteger': <class '__main__.BitsInteger'>, '__loader__': <_frozen_importlib.SourceFileLoader object at 0x7ff05d2eb4a8>, '__package__': None, 'Bit': <__main__.BitsInteger object at 0x7ff05d2ae3c8>, '__doc__': None}
>>>
正如你可以看到b
實際類型爲BitsInteger
的原因是什麼回事的是,當你寫:
@singleton_function
def Bit():
"""Bit docstring"""
...
return BitsInteger(1)
你真的剛開語法糖這樣的:
def Bit():
"""Bit docstring"""
...
return BitsInteger(1)
Bit = singleton_function(Bit)
在這種情況下,Bit
是singleton_function
的返回值,它實際上是BitsInteger
。我發現,當你消除語法糖時,它會更清晰地發生在這裏。
如果你想有一個裝飾的方便,不改變文檔字符串我推薦使用wrapt
import wrapt
class BitsInteger:
"""BitsInteger docstring"""
def __init__(self, num):
pass
def singleton(cls):
return cls()
@wrapt.decorator
def singletonfunction(func):
return func()
@singletonfunction
def Bit():
"""A 1-bit BitField; must be enclosed in a BitStruct"""
return BitsInteger(1)
b = Bit
print("b.__doc_ :", b.__doc__)
此輸出:
b.__doc_ : A 1-bit BitField; must be enclosed in a BitStruct
現在,當你在看Vars()
您會看到'b': <FunctionWrapper at 0x7f9a9ac42ba8 for function at 0x7f9a9a9e8c80>
不再是BitInteger
類型。我個人喜歡使用包裝,因爲我立即得到我想要的東西。實現該功能並覆蓋所有邊緣案例需要付出努力,而且我知道包裝已經過良好測試並按預期工作。
本質上'位= BitInteger(1)'。你在位定義中有一個錯字,它不會返回一個類,而是一個實例。更糟糕的是,它似乎不適用於PY3,它不會繼承/ >>操作符。 – ArekBulski
我用cPython 3.5運行了這個。如果您可以將「BitsInteger」類的一些定義與您在問題中需要實現的內容相結合,可能會幫助我在這裏改進答案。我不完全清楚你想解決的原始問題是什麼。你是否需要'Bit'來調用並始終返回相同的(單例)對象? – shuttle87
位應該是一個類實例,它具有從函數而不是類獲取的文檔字符串。而已。我接受你的解決方案,即使它有時可以工作。 – ArekBulski