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 the 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!

- 6,397
- 2
- 41
- 52
-
3Might want to show us your actual code. – FogleBird Jun 19 '11 at 15:27
-
added the code, 10x. Didn't format it properly though. I'll see what can be done. – asenovm Jun 19 '11 at 15:34
-
@iLate, looks like you have a mix of tabs and spaces. (Mix of tabs and spaces laughs evilly...). – senderle Jun 19 '11 at 15:40
-
It was all tabs, hehe :) – asenovm Jun 19 '11 at 15:42
-
@iLate, still looks kinda weird. Instead of just indenting the top-level declarations four spaces, why don't you indent all the code by four spaces using the `{}` button at the top of the edit window? – senderle Jun 19 '11 at 15:45
-
I'm trying to run/debug your code-there's some errors besides what you've described; I'll fix it up and see what I can do. – li.davidm Jun 19 '11 at 15:47
-
10x, but I'd be happy to just have this question answered. This is part of a homework I'm having, so please don't post any code ( that's why I have originally not posted my code ) and I started writing it not long ago so that's why there are quite some things to be done. I'll add the homework tag as well. – asenovm Jun 19 '11 at 15:51
-
1@iLate: I'm sorry - I already posted some code, but it's mostly incomplete - is that okay? I just fixed what's necessary to make it run and provided some hints. – li.davidm Jun 19 '11 at 15:58
2 Answers
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
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.

- 11,736
- 4
- 29
- 31
-
10x, for the answer!:) Yes, that was my actual code and it worked for me(I didn't copy the imports).But class_dict can't be a dict( since the point here is to add multiple functions with one and the same name that differ only by the annotations of their parameters which can't be done if we use a dict(this way only the last function will be added). I want to check the types of the parameters collide is called with and that's why i nspect what is passed to `__call__` but not what is in the class_dict(I'll invoke functions from class_dict once i see which one exactly should i invoke). – asenovm Jun 19 '11 at 16:11
-
@iLate, is the assignment to use metaclasses, multimethods, or neither? If it's one of the latter two, you should really check out that article -- it's dead simple. – senderle Jun 19 '11 at 16:13
-
doh, actually the idea for appending to dict[key] instead of using a list will be quite useful. Thanks! – asenovm Jun 19 '11 at 16:14
-
btw, the NoneType error I was getting was due to the fact that i tried using descriptors to solve the problem and I had left `__get__` in the body of OverloadedFunction with empty body which I didn't copy :D Sorry for the bother and 10x :) – asenovm Jun 19 '11 at 16:32