I'm trying to change the dictionary of a python class so that everytime a function object is added to the dictionary I add an instance of my class where I redefine __call__
instead.
I use a custom dictionary for the metaclass and in __setitem__
of the dictionary class I'm instantiating the class that I use to change the behaviour of the added functions and I add a not NoneType object to th开发者_运维知识库e dictionary. However, when I instantiate the class with the functions I'm wrapping and try to call the respective function I get a "NoneType not callable" error and the function object that I've wrapped in the class dictionary is = None. Any ideas why this might happen? Thanks!
Before I start - is the posted code your actual code? It doesn't actually work for me under Python 3.2 - I've fixed it up a bit. Here's what I've changed, to start:
class_dict = list()
is now
class_dict = {}
and in OverloadedFunction.__call__
:
for fkey, function in class_dict.items():
inspect_t = inspect.getfullargspec(function)
print(inspect_t)
in member_dict.__setitem__
:
if value.__class__.__name__ == "function":
class_dict[key] = value
dict.__setitem__(self,key,OverloadedFunction(key,value))
I believe this is what you intended. I never got the NoneType not callable
error - with these modifications (plus import inspect
at the top), your code works and prints the argument specification:
$ 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'>})
Now, you want to implement the multimethod - the modifications I made preclude that, since your multimethods are overwritten on each call to __setitem__
, so you can work from there (perhaps use collections.defaultdict(list)
and append
to class_dict[key]
instead).
May I suggest something? I don't think you need a metaclass - http://www.artima.com/weblogs/viewpost.jsp?thread=101605 provides a multimethod implementation for Python 2.x that's very simple.
I am not sure what you have done exactly, but you might find setdefault useful:
setdefault(key[, default])
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.
Detailed info: Use cases for the 'setdefault' dict method
精彩评论