Namespaces — let’s do more of those! (Python)

Namespaces are one honking great idea — let’s do more of those!
– The Zen of Python (PEP 20) by Tim Peters

In the quest for order and heirarchy in our code, namespaces are our chief weapon (along with fear and surprise). Namespaces come in 2 forms in python: Implicitly inside classes and functions, and explicitly as modules. Subtleties aside, modules are just namespaces with an odd usage: They must be files, and only other modules can parent them.

Of the implicit namespaces, each have their own “quirks”:

  • Classes – these namespaces have two modes – “normal” and instanciated, and both have odd behaviours.
  • Functions – their internal space cannot be accessed from the outside; they only provide locality.

All this babble was meant to demonstrate that these are not enough. You can’t always keep your code organized if your choice is only between file seperation, twisted behaviour or no-public policy.

What else could I possibly want?

Well, for example, dividing responsibilities inside a class. Classes infamously have several responsibilities, and while they all must reside inside the same class, there’s no reason why they should be blended inside each other.
Consider all of the GUI libraries you ever used. Now consider the following hypothetical GUI window:

class YetAnotherGuiWindow(whatever):
    ...
    namespace spatial:
        location = property(_get_loc, _set_loc)
        size = property(_get_size, _set_size)
        def move(self, where_to):
            ...

    namespace visual:
        color = property(_get_color, _set_color)
        ...
    ...

#Somewhere Else
guiwindow.spatial.move( guiwindow.spatial.pos + (5,5) )
guiwindow.visual.color = Colors.Black
...

Think how wonderful it would be to perform dir(guiwindow.visual) and see only visual possiblities, without all the other 500 attributes. Want to find an event? dir(guiwindow.events), it’s a rather short list. It would also be a lot clearer to the reader that when you try to access “background_process” you mean “threads.background_process” and not “cool_visual_filter_effects.background_process”.

There are more examples I could think of.

At this point I can foresee a possible response, that I wish to address in advance. People might propose that I rename methods to fake a namespace, and that the dir listing can work by filtering the names for that fake namespace. This would vaguely emulate what I’m hoping for, but I can’t help comparing it to writing C++ using C structs and function pointers.

I like your idea. Is there anything I can do with what python currently offers?

I have given this some thought. The short answer is: No. Python’s namespaces are crippled, and this cannot be solved.  The long answer is: Maybe, depends on what you want. You could use a class to provide a namespace, in which all methods (perhaps through a decorator for each) would recieve the parent class’ instance as self, rather than their own. This is a bit tedious, as it requires addition to every function, so I tried to see if I can use python’s dynamic and introspective nature to my advantage:

def make_namespace(self, ns_cls):
    "This code iterates all functions in ns_cls and binds them to self"
    for attr_name in dir(ns_cls):
        attr = getattr(ns_cls,attr_name)
        if type(attr) == types.MethodType:
            setattr(ns_cls, attr_name, attr.__get__(self) )

Usage:

class YetAnotherGuiWindow:
    def __init__(self, pos, size, ...):
        ...
        self._size = size
        make_namespace(self, self.spatial)

    class spatial:
        ...
        def get_size(self):
            return self._size
        def set_size(self, size):
            self._size = size

...
#Somewhere Else
guiwindow.spatial.set_size( (100, 100)  )

This seems to work fine for methods, but not for properties.
In fact, I couldn’t manage to write any code that would work for properties. Readers are welcome to see this as a challenge to produce such code. Honorable mentions promised to solvers.

About these ads

10 Responses to Namespaces — let’s do more of those! (Python)

  1. lorg says:

    Heya
    My first comment on your blog. Mazal Tov on the blog!

    My thoughts on your post:
    1. It happened to me before when I needed some namespace for a few functions. I usually use some singleton class for that (potentially with staticmethod-s)

    2. I remember reading some time ago a post in Python-Ideas about changing the syntax, so that you could do something like
    [python]
    class MyClass:
    ….

    MyClass Foo:
    ….
    [/python]
    Alas, I can’t find the original post so I won’t elaborate on the semantics, but your post reminded me of this idea. Given this idea, it would be quite simple to implement your idea.

    3. Another related issue is enums. From time to time I need a few constants, and I usually either keep them in an enum, or create an ad-hoc class for them. However, the official recommendation from GvR is not to do that.

    4. One thing that annoys me with too much namespaces is that it’s sometimes too much work to locate a function. I think that given your proposal, a regular dir() call should return a kind of a dictionary, like so
    {“spatial”: ["location","size"],”visual”:["color"] }
    What do you think?

  2. erezsh says:

    Thanks!

    1. It’s relatively easy to solve with a custom decorator for each function. But properties still require special treatment.

    2. Thanks, it’s an interesting idea (but I can settle for less).

    3. I think a namespace would be a bit better suited for enums than a class (though this is of small relevance)

    4. Interesting, I like it. It might make automatic searching a bit awkward, but not overly, as a function can be written for it.

  3. Carl says:

    Python 3 will have an __dir__ special method that you might find useful.

  4. Jay says:

    “In fact, I couldn’t manage to write any code that would work for properties.”

    That’s because you’re not using new-style classes. You have to inherit from object unless you’re using 3.0.

  5. erezsh says:

    Thanks, but I couldn’t get it to work using new-style classes.

    The problem is that properties are sort of a magic in Python, and I can’t find a way to add (or change) them in run-time..

  6. Pwilson says:

    If I understand you correctly, you’re after something as described here:

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/409366

    I have used this recipie to create mini-embedded statemachines within a class.

  7. erezsh says:

    No, this is not exactly what I’m looking for.
    If I understand the code correctly, doing something like: inst.namespace.some_var might return inst.some_var if it doens’t exist inside ‘namespace’, which kinda ruins the point of having namespaces.
    This probably could’ve been made to work, if I could know if the caller is inside the class or the outside of it. However, I’m pretty sure it’s not possible to do in Python.

  8. CialisEl says:

    Nice Blog. Good Look

  9. erezsh says:

    Carl, isn’t it __methods__ and __members__?

  10. [...] If you’re, for some reason, a frequent reader of this blog, you’d remember how in a previous post I suggested a hack to allow namespaces inside Python classes. However, it was largely incomplete [...]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: