Search code examples
pythondjangonamespacespython-module

python shared global module variable issue


I'm writing small application for my Django project. The idea is to create some kind of widgets - small view functions that can be added in templates via inclusion tags to display some aside information (e.g. blog records, quick-links lists, menus etc). I want to create something similar to default templatetag registering mechanism for this purpose. Generally I need the following components:

  • custom decorator to register these view functions
  • some function that will search for specific modules in all installed apps ('widgets.py' for now) at startup (possibly called from settings.py)

What I wrote by now looks like this:

# -*- coding: utf-8 -*-


REGISTERED_WIDGETS = []

class Library(object):
    """
    Utility class for registering defined widgets
    """
    def widget(self, view=None, name=None, form_class=None):
        if name is None:
            name = view.__name__
        def decorator(view):
            print 'registering', view
            REGISTERED_WIDGETS.append((view, name, form_class))
            def wrapper(request, *args, **kwargs):
                return view(request, *args, **kwargs)
            return wrapper
        if view is not None:
            return decorator(view)
        else:
            return decorator

def search_widgets():
    """
    Search for 'widgets.py' modules inside installed applications and import them,
    hence initializing its registration
    """
    from django.conf import settings

    for app in settings.INSTALLED_APPS:
        try:
            module = __import__(app + '.widgets')
            print module
        except ImportError:
            pass
        else:
            print 'Imported widgets from ', app

if __name__ == '__main__':
    search_widgets()
    print REGISTERED_WIDGETS

To test it I added this stub widget in widgets.py inside one of my applications:

# -*- coding: utf-8 -*-

from experiments.widgets.base import Library

register = Library()

@register.widget(name='dummy')
def dummy_widget(request):
    pass

I stuck now one silly issue - when run this module I suppose to see REGISTERED_WIDGETS variable filled with found widgets, but it's empty. Actually I see this output:

>>> %run widgets/base.py
<module 'django' from '/usr/lib/python2.7/dist-packages/django/__init__.pyc'>
Imported widgets from  django.contrib.admin
registering <function dummy_widget at 0x364f320>
<module 'experiments' from '/home/east825/Development/pycharm-experiments/experiments/../experiments/__init__.pyc'>
Imported widgets from  experiments.layout
[]

It seems that I forgot something very important about python shared global variables behavior. Any advices?


Solution

  • It could be possible that your module base.py gets imported twice?

    Add a print at the beginning of base.py with a "print 'base.py executed'" or something.

    edit: or even better, print id(REGISTERED_WIDGETS)