これは私の最初の質問です。私はこの問題について多くのことを尋ねましたが、私はそれに対処する有益な情報は見つけられませんでした。functools.wrapsは、mappingproxy型の代わりにdict型の__dict__を返します
Python 3で私のコードの一般的な推奨されないPythonデコレータを作成しようとしています。目的は2つのことを行う関数またはクラスを正しくラップすることです:deprecationに関する警告を表示し、__doc__
の前にdeprecation情報sphinx
によっても処理することができます)。私は、私が望むものの大部分を整理したと思いますが、私はまだスフィンクスと闘っていますが、functools.wraps
の行動について興味があるものが見つかりました。基本的に、ラップされたクラスの__dict__
はタイプdict
であり、ラップされていないクラスのタイプはmappingproxy
です。ここで
は、いくつかのショーケースコードです:
import functools
class Deprecated(object):
def __call__(self, cls):
myassigns = functools.WRAPPER_ASSIGNMENTS
myassigns += ('__mro__',)
@functools.wraps(cls, assigned=myassigns)
def new_func(*args, **kwargs):
warnings.warn(message, category=DeprecationWarning, stacklevel=2)
return cls(*args, **kwargs)
return new_func
@Deprecated()
class SomeOldClass:
def some_method(self, x, y):
return x + y
class SomeClass:
def some_method(self, x, y):
return x + y
print(type(SomeOldClass.__dict__))
print(type(SomeClass.__dict__))
そして出力:
<class 'dict'>
<class 'mappingproxy'>
はfunctools.wraps
誤動作ですか私が何か間違ったことをやっていますか?
"ラップされたクラス"は関数です。 'functools.wraps'は何をすると思いましたか? – user2357112
'some_method'をラップすることを意味しましたか?それは、クラスそのものをラップしたものです(深くは見ていませんが、インスタンスを作成するときに警告する必要があると思います)が、名前はクラスではなくラッパー関数を参照するということも意味します'SomeOldClass'では明示的に' __wrapped__'属性にドリルスルーすることなくクラス関連のものは表示されません。このようにクラスを非推奨にするには、ラッパーがクラスにドリルして明示的に '__init__'または' __new__'をラップして(元の 'cls'を返して)、クラスをラップする関数を返しません。 – ShadowRanger
@ user2357112私は私のラッピング関数を隠すことを期待しています。私の変更を除いて、元のクラスであることが表示されます。具体的には、私は廃止されたClassで 'help()'のような関数を適切に動作させたいと思っていました。 – j3mdamas