Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python共享全局模块变量问题_Python_Django_Namespaces_Python Module - Fatal编程技术网

python共享全局模块变量问题

python共享全局模块变量问题,python,django,namespaces,python-module,Python,Django,Namespaces,Python Module,我正在为我的Django项目写一个小应用程序。我们的想法是创建一些小部件——小视图功能,可以通过包含标签添加到模板中,以显示一些旁白信息(例如博客记录、快速链接列表、菜单等)。为此,我想创建类似于默认templatetag注册机制的东西。一般来说,我需要以下组件: 用于注册这些视图函数的自定义装饰器 在启动时(可能从settings.py调用)在所有已安装的应用程序中搜索特定模块的一些功能('widgets.py'现在) 我现在写的是这样的: # -*- coding: utf-8 -*-

我正在为我的Django项目写一个小应用程序。我们的想法是创建一些小部件——小视图功能,可以通过包含标签添加到模板中,以显示一些旁白信息(例如博客记录、快速链接列表、菜单等)。为此,我想创建类似于默认
templatetag
注册机制的东西。一般来说,我需要以下组件:

  • 用于注册这些视图函数的自定义装饰器
  • 在启动时(可能从settings.py调用)在所有已安装的应用程序中搜索特定模块的一些功能('widgets.py'现在)
我现在写的是这样的:

# -*- 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
为了测试它,我在一个应用程序的widgets.py中添加了这个存根小部件:

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

from experiments.widgets.base import Library

register = Library()

@register.widget(name='dummy')
def dummy_widget(request):
    pass
我现在遇到了一个愚蠢的问题——当运行这个模块时,我想看到REGISTERED_WIDGETS变量中填充了找到的WIDGETS,但它是空的。实际上我看到了这个输出:

>>> %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
[]
>>%运行widgets/base.py
从django.contrib.admin导入的小部件
登记
从experiments.layout导入的小部件
[]
似乎我忘记了一些关于python共享全局变量行为的非常重要的事情。
有什么建议吗?

您的module base.py可能会被导入两次

在base.py的开头添加一个带有“print'base.py executed'”或其他内容的打印


编辑:或者更好,打印id(已注册的\u小部件)

是的,你说得对-我添加了
打印id(已注册的\u小部件)
并看到这个列表创建了两次:第一次在主脚本中,第二次在第一次导入时通过导入调用。这很奇怪,我总是认为一旦模块加载到sys.modules中,它就不会再导入了。但我仍然不知道如何解决这个问题,事实上这不应该是原因——在第二次导入时,列表不会再次创建,这次添加的元组应该保留在其中,不是吗?我还尝试创建这个列表库类的字段,但无论如何都没有帮助。有什么想法吗?如果你看到两次打印,这意味着定义了两个不同的REGISTERED_小部件。第一个是打印的,第二个不是空的。检查python文档:问题似乎出在导入上,您应该像示例中那样添加参数globals和local。我认为原因是导入了两次,因为它看不到模块已经导入(因为您没有指定全局变量)。试试看,让我知道:)不,没用。在使用导入和共享全局变量玩了一段时间之后,我想到了一个主意——我看不到模块中的这些更改,这些变量已经定义,因为它已经定义了它们自己的私有副本,然后您将其作为主脚本运行。我重写了我的应用程序,将注册的小部件存储为
对象的字段,然后在
搜索小部件
中,我将此字段值附加到
注册的小部件
(实际上几乎和Django本身一样)。这正如预期的那样有效。感谢您将我推向正确的解决方案。我不明白这句话:“我看不到模块内部的更改,因为它定义了这些变量,因为它定义了它们自己的私有副本,然后您将其作为主脚本运行”:,我很高兴它对您有所帮助:)我的意思是,如果您有一个脚本,其中定义了一些全局可变值,您有其他模块导入这个值,并以某种方式更改这个变量(直接调用这个变量的某些方法,使用一些特殊的函数或类-这并不重要)。然后在您的第一个模块中,您尝试运行类似于
if uuuuu name_uuuuuu=='uuuuuuu main_uuuuuu':import module2;模块2.change_global();打印全局
-您将看不到任何更改,因为实际上存在这些变量的不同实例-一个在
sys.modules[''''main.']
中,另一个在
sys.modules['module1']
中。