Pythonクラスのディクショナリを変更して、関数オブジェクトがディクショナリに追加されるたびに、__call__
代わりに再定義するクラスのインスタンスを追加しようとしています。メタクラスにカスタムディクショナリを使用し__setitem__
、ディクショナリクラスで、追加された関数の動作を変更するために使用するクラスをインスタンス化し、NoneTypeではないオブジェクトをディクショナリに追加します。ただし、ラップしている関数を使用してクラスをインスタンス化し、それぞれの関数を呼び出そうとすると、「NoneType not callable」エラーが発生し、クラスディクショナリにラップした関数オブジェクトは=Noneになります。なぜこれが起こるのか、何か考えはありますか?ありがとう!
2 に答える
あなたが正確に何をしたかはわかりませんが、setdefaultが役に立つかもしれません:
setdefault(キー[, デフォルト])
キーが辞書にある場合は、その値を返します。そうでない場合は、デフォルトの値でキーを挿入し、デフォルトを返します。デフォルトのデフォルトはなしです。
始める前に - 投稿されたコードは実際のコードですか? Python 3.2 では実際には動作しません。少し修正しました。変更した内容は次のとおりです。
class_dict = list()
今でしょ
class_dict = {}
とでOverloadedFunction.__call__
:
for fkey, function in class_dict.items():
inspect_t = inspect.getfullargspec(function)
print(inspect_t)
でmember_dict.__setitem__
:
if value.__class__.__name__ == "function":
class_dict[key] = value
dict.__setitem__(self,key,OverloadedFunction(key,value))
これはあなたが意図したものだと思います。NoneType not callable
エラーが発生したことはありません-これらの変更(さらにimport inspect
上部)により、コードは機能し、引数の仕様が出力されます:
$ python3 temp.py
FullArgSpec(args=['self', 'a', 'b'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={'a': <class '__main__.Asteroid'>, 'b': <class '__main__.Asteroid'>})
ここで、マルチメソッドを実装する必要があります。マルチメソッドは への呼び出しごとに上書きされるため、私が行った変更によりそれが不可能になり__setitem__
、そこから作業することができます (代わりにcollections.defaultdict(list)
andappend
を使用する可能性がありclass_dict[key]
ます)。
何か提案してもいいですか?メタクラスは必要ないと思います - http://www.artima.com/weblogs/viewpost.jsp?thread=101605は、非常に単純な Python 2.x のマルチメソッド実装を提供します。