尽管有__init__.py,但尝试在非包装错误中尝试相对导入

App*_*rew 5 python python-2.7 osx-lion

我有一个包裹cclogger.此目录有一个__init__.py文件,其中包含一些用于加载配置的代码.当我尝试api_main.py使用以下命令在该目录中运行该文件时...

python -m cclogger.api_main
Run Code Online (Sandbox Code Playgroud)

我得到以下错误: -

config loaded
Instantiating DB with: cclogger/test123@localhost:x
Instantiated ParseCentral
Register parser called by : CitiIndia
Registered parser for email:  CitiAlert.India@citicorp.com
Instantiated SmsParseCentral
Register parser called by : Citi Bank
Registered sms parser for address:  lm-citibk
Register parser called by : HDFC Bank
Registered sms parser for address:  am-hdfcbk
Traceback (most recent call last):
  File "/Users/applegrew/Dropbox/Credit Expense/cclogger/cclogger/api_main.py", line 4, in <module>
    from .bottle import run, default_app, debug, get
ValueError: Attempted relative import in non-package
Run Code Online (Sandbox Code Playgroud)

错误上方显示的消息来自导入的同一包中的模块__init__.py.

api_main.py中的代码是: -

import re
import os

from .bottle import run, default_app, debug, get
from .common_util import date_str_to_datetime, UTCOffset, date_filter

#app = Bottle()

default_app().router.add_filter('date', date_filter)

from . import api, dev

@get('/index')
def index():
    return "CCLogger API main live and kicking."

if dev:
    debug(True)
    run(reloader=True, port=9000)
else:
    os.chdir(os.path.dirname(__file__))
    application = default_app()
Run Code Online (Sandbox Code Playgroud)

我有python 2.7.1.

我究竟做错了什么?您可以在https://github.com/applegrew/cclogger/tree/master/cclogger上查看完整代码.

luc*_*asg 7

你不能直接将python模块作为脚本运行(我真的不知道原因).

编辑:原因在PEP338中解释,这是该"-m"选项的规格.

2.5b1的发布显示了这个PEP和PEP 328之间令人惊讶的(虽然回顾起来很明显)相互作用 - 显式相对导入不能从主模块起作用.这是因为相对导入依赖于__name__确定当前模块在包层次结构中的位置.在主模块中,值__name__始终为__main__,因此显式相对导入将始终失败(因为它们仅适用于包内的模块).

对于2.5版本,建议始终在任何旨在用作主模块的模块中使用绝对导入

要测试您的应用程序,请在函数中封装api_main并创建一个运行主循环的顶级main.py文件:

cclogger/api_main.py:

import re
import os


from .bottle import run, default_app, debug, get
from .common_util import date_str_to_datetime, UTCOffset, date_filter

#app = Bottle()


def main():
    default_app().router.add_filter('date', date_filter)

    from . import api, dev

    @get('/index')
    def index():
        return "CCLogger API main live and kicking."

    if dev:
        debug(True)
        run(reloader=True, port=9000)
    else:
        os.chdir(os.path.dirname(__file__))
        application = default_app()
Run Code Online (Sandbox Code Playgroud)

/main.py:

from cclogger import api_main


if __name__ == '__main__':
    api_main.main()
Run Code Online (Sandbox Code Playgroud)

您可以通过键入运行应用程序python main.py,python -m mainpython -c "import cclogger.api_main; api_main.main()".

PS:感谢链接完整的源代码,它总是比问题提供的存根更有帮助.