I have this scenario, where I need to ask a nested class to append items to a list in the outer class. Heres pseudocode thats similar to what Im trying to do. How would I go about getting it to work?
class Outer(object):
outerlist = []
class Inner(object):
def __call__(self, arg1):
outerlist.append(arg1)
if __name__ == "__main__":
f = Outer()
f.Inner("apple")
f.Inner("orange")
print f.outerlist()
This is what I hope to see – apple, orange
Details:
OS X, Python 2.7
Now that I understand your design, you’re going about things all wrong.
First, Outer is a class; it doesn’t get
__call__ed. Your line 17 is just going to construct an emptyOuterobject and do nothing with it. If you want to “call” theOuterobject, you can define an__init__method—or, as Sheena suggests, define a__new__and intercept the initialization, since you don’t actually need the initialized object anyway.Honestly, I don’t think someone who doesn’t understand how
__call__works yet should be trying to build something tricky like this yet. But if you insist, read on.It’s a very odd, and probably bad, design to collect this kind of stuff in a class instead of an instance. Keep in mind that class variables are effectively globals, with all that entails. If you try to use
Outerreentrantly, or from multiple threads/event handlers/greenlets/whatever, the uses will end up stomping all over each other. Even if you think that isn’t possibly going to be a problem now, it likely will at some point in the future.You could create an
Outerinstance, and use its members as decorators. For example:But I’m not sure that’s much better. The entire design here seems to involve performing actions at the module level, even though it looks like you’re just defining normal functions and calling a function at the end. The fact that you’ve managed to confuse yourself should be evidence of how confusing a design this is.
But if you do want to do that, what you probably want to do is define classes inside the
Outer.__init__method, and assign them to instance members. Classes are first-class values, and can be assigned to variables just like any other values. Then, use the__init__(or__new__) methods of those classes to do the work you wanted, making the classes simulate functions.This may seem confusing or misleading. But remember that the whole point of what you’re trying to do is to use a class in a way that it looks like a method, so that kind of confusion is inherent in the problem. But if you prefer, you can write decorators as functions (in this case, as normal instance methods of
Outer); it just makes a different part of the problem harder instead of this part.A more normal way to design something like this would be to make
Outera perfectly normal class that people can either subclass or create instances of, and provide an explicit non-fancy way to attach handler methods or functions to URLs. Then, once that’s working, design a way to simplify that handler registration with a decorator.