2016-09-17 11 views
3

私は、それらをシングルトンに変更する関数とクラスデコレータを持っていますが、ドキュメントストリングは一種落としています。 Transforming関数は、上書きする必要がある独自のdocstringを持つクラスオブジェクトを返します。これを回避するにはどうしたらいいですか? Bitの検査クラスオブジェクトのドキュメントストリングをプログラム的に変更する

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) 

BitIntegerドキュメンテーション文字列ではなく、機能の1が得られます。

答えて

1

は、元のバージョンは、このようなものであると仮定しましょう:

b.__doc_ : BitsInteger docstring 

これは、あなたが期待するものではないかもしれません。

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を見ることができるように本当に起こっていることということですので、 BitsInteger

理由がある

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

:我々はpython -i original.pyで実行すると、私たちは周りに本当にここで何が起こっているかを見てすることができますあなたが書くとき:

def Bit(): 
    """Bit docstring""" 
    ... 
    return BitsInteger(1) 
Bit = singleton_function(Bit) 
01:

@singleton_function 
def Bit(): 
    """Bit docstring""" 
    ... 
    return BitsInteger(1) 

あなたは本当にこれだけのために糖衣構文を取得しています

この場合、Bitsingleton_functionの戻り値です。実際はBitsIntegerです。文法的な砂糖を取り除くと、ここで何が起きているのかがはっきり分かります。あなたが見たときに今

b.__doc_ : A 1-bit BitField; must be enclosed in a BitStruct 

:あなたはドキュメンテーション文字列を変更しないデコレータの利便性を持っているしたい場合

私は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__) 

この出力を使用してお勧めしますVars() は、もはやBitIntegerタイプではありません。個人的には、私はすぐに欲しいものを得るので、ラップを使うのが好きです。その機能を実装し、すべてのエッジケースをカバーするのには努力が必要です。私は、wraptがうまくテストされ、意図どおり動作することを知っています。

+0

本来、Bit = BitInteger(1)です。ビット定義にタイプミスがありますが、クラスはインスタンスを返しません。さらに悪いことに、それはPY3で動作するようではなく、/ >>演算子を継承しません。 – ArekBulski

+0

私はcPython 3.5でこれを実行しました。 'BitsInteger'クラスの定義のいくつかを、あなたがその質問で達成する必要があるものと一緒に置くことができれば、ここで答えを改善するのに役立つかもしれません。私はあなたが解決しようとしている元の問題が何であるかについて完全にはっきりしていません。呼び出し可能で、常に同じ(シングルトン)オブジェクトを返すには 'Bit'が必要ですか? – shuttle87

+0

ビットは、クラスインスタンスでなくてはならず、クラスではなく関数から取得したドキュメントストリングです。それでおしまい。私はあなたの解決策を受け入れます。それは時にはうまくいきます。 – ArekBulski

関連する問題