代码之家  ›  专栏  ›  技术社区  ›  balu

虽然导入了python模块的包,但访问它失败

  •  3
  • balu  · 技术社区  · 14 年前

    我的Django项目的目录层次结构如下:

    + pybsd
    |---+ devices
        |---+ templates
        |---+ views
            |---+ interaction
                |---- __init__.py
                |---- geraete.py
                |---- geraetemodelle.py
                |---- geraetegruppen.py
            |---- __init__.py
            |---- ajax.py
            |---- html.py
            |---- misc.py
        |---- __init__.py
        |---- urls.py
    |---- __init__.py
    |---- urls.py
    

    (请原谅德国人的名字。我不想在这里替换它们,因为它会在尝试您希望建议的解决方案和回答您的问题时添加另一个可能的错误源。)

    每个请求 http://URL/devices/ *发送到/devices中的urls.py文件:

    # ...
    from views import html, ajax, misc, interaction
    
    urlpatterns = patterns('', 
        # ...
        (r'^ajax/update/(?P<table>[a-z_]+)$', ajax.update),
        (r'^ajax/delete/(?P<table>[a-z_]+)$', ajax.delete),
        (r'^ajax/select_options/(?P<table>[a-z_]+)$', ajax.select_options),
    
        (r'^interaction/geraete/info/(?P<geraet>\d+)$', interaction.geraete.info),
        (r'^interaction/geraete/delete/(?P<geraet>\d+)?$', interaction.geraete.delete),
        (r'^interaction/geraetemodelle/delete/(?P<geraetemodell>\d+)?$', interaction.geraetemodelle.delete),
        (r'^interaction/geraetegruppen/delete/(?P<geraetegruppe>\d+)?$', interaction.geraetegruppen.delete),
        # ...
    )
    

    除了引用交互包的定义外,所有URL定义都可以工作。我不断地得到以下错误:

    File "/home/simon/projekte/pybsd/../pybsd/devices/urls.py", line 33, in `<module>`
      (r'^interaction/geraete/info/(?P<geraet>\d+)$', interaction.geraete.info),
    AttributeError: 'module' object has no attribute 'geraete'
    

    我仔细检查了一下 __init__.py 文件不包含任何内容。

    也许你已经找到了(与python或django相关的?)我犯了错误,显然看不见。如果没有,请继续阅读。无论如何,感谢你阅读这篇长文章!


    隔离问题

    第一试验

    如果我将视图函数作为字符串提供,它就会工作:

    (r'^interaction/geraete/info/(?P<geraet>\d+)$', 'devices.views.interaction.geraete.info'),
    (r'^interaction/geraete/delete/(?P<geraet>\d+)?$', 'devices.views.interaction.geraete.delete'),
    (r'^interaction/geraetemodelle/delete/(?P<geraetemodell>\d+)?$', 'devices.views.interaction.geraetemodelle.delete'),
    (r'^interaction/geraetegruppen/delete/(?P<geraetegruppe>\d+)?$', 'devices.views.interaction.geraetegruppen.delete'),
    

    …或者在导入中添加另一行:

    from views.interaction import geraete, geraetemodelle, geraetegruppen
    

    使用 from views.interaction import * 但是,也不起作用,导致相同的错误消息。


    第二试验

    我在/devices中创建了一个文件test.py:

    from views import interaction
    print dir(interaction)
    

    输出:

    simon@bsd-simon:~/projekte/pybsd/devices$ python test.py
    ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
    

    同样,我在交互包中创建的模块没有任何迹象(geraete.py、geraetemodelle.py、geraetegruppen.py)。

    与urls.py不同,尝试 from view.interaction import geraete, geraetegruppen, geraetemodelle 在test.py结果中 ImportError: No module named view.interaction 这次。


    第三试验

    我启动了Django Shell:

    $ python manage.py shell
    >>> import devices.views.interaction.geraete
    >>> dir(devices.views.interaction.geraete)
    ['Abteilung', 'Auftrag', 'Auftragsvorlage', 'Geraet', 'Geraetegruppe', 'Geraetemodell', 'HttpResponse', 'HttpResponseBadRequest', 'HttpResponseRedirect', 'Raum', 'Standort', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'delete', 'info', 'models', 'move', 'render_to_response']
    >>> 
    
    $ python manage.py shell
    >>> from devices.views.interaction import geraete
    >>> dir(geraete)
    ['Abteilung', 'Auftrag', 'Auftragsvorlage', 'Geraet', 'Geraetegruppe', 'Geraetemodell', 'HttpResponse', 'HttpResponseBadRequest', 'HttpResponseRedirect', 'Raum', 'Standort', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'delete', 'info', 'models', 'move', 'render_to_response']
    >>> 
    
    $ python manage.py shell
    >>> import devices.views.interaction
    >>> devices.views.interaction.geraete
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
    AttributeError: 'module' object has no attribute 'geraete'
    >>> dir(devices.views.interaction)
    ['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   Thomas Wouters    14 年前

    当模块存在于包中,并且您导入包时,python不会自动导入包中的所有模块。程序中的某些内容需要导入要使用的模块。那也可以是你的 urls 模块:

    import views.interaction.gaerete
    

    或者,如果你想要 interaction.garaete 导入时始终可用 interaction 它可以是 interaction/__init__.py :

    import gaerete
    
        2
  •  0
  •   Thomas Wouters    14 年前

    当你说

    import devices.views.interaction
    

    以后

    interaction.geraete
    

    巨蟒寻找 杰拉特 __init__.py 交互包中的模块。

    如果你想看这部作品,你可以包括 import geraete π介子 模块。

        3
  •  0
  •   Olivier Verdier    14 年前

    如果子模块未导入到 __init__.py 文件:

    import interaction.geraete