Python + WSGI - 无法从目录中导入自己的模块?

12
我对Python很陌生,我查阅了如何从目录/子目录中导入自定义模块的相关信息。例如这个这个。以下是我的文件结构:
index.py
__init__.py
modules/
  hello.py
  HelloWorld.py
  moduletest.py

index.py,

# IMPORTS MODULES
import hello
import HelloWorld
import moduletest

# This is our application object. It could have any name,
# except when using mod_wsgi where it must be "application"
def application(environ, start_response):

    # build the response body possibly using the environ dictionary
    response_body = 'The request method was %s' % environ['REQUEST_METHOD']

    # HTTP response code and message
    status = '200 OK'

    # These are HTTP headers expected by the client.
    # They must be wrapped as a list of tupled pairs:
    # [(Header name, Header value)].
    response_headers = [('Content-Type', 'text/plain'),
                       ('Content-Length', str(len(response_body)))]

    # Send them to the server using the supplied function
    start_response(status, response_headers)

    # Return the response body.
    # Notice it is wrapped in a list although it could be any iterable.
    return [response_body]

init.py,

from modules import moduletest
from modules import hello
from modules import HelloWorld

modules/hello.py,

def hello():
    return 'Hello World from hello.py!'

modules/HelloWorld.py,

# define a class
class HelloWorld:
    def __init__(self):
        self.message = 'Hello World from HelloWorld.py!'

    def sayHello(self):
        return self.message

modules/moduletest.py,

# Define some variables:
numberone = 1
ageofqueen = 78

# define some functions
def printhello():
    print "hello"

def timesfour(input):
    print input * 4

# define a class
class Piano:
    def __init__(self):
        self.type = raw_input("What type of piano? ")
        self.height = raw_input("What height (in feet)? ")
        self.price = raw_input("How much did it cost? ")
        self.age = raw_input("How old is it (in years)? ")

    def printdetails(self):
        print "This piano is a/an " + self.height + " foot",
        print self.type, "piano, " + self.age, "years old and costing\
        " + self.price + " dollars."

可是通过 Apache WSGI,我遇到了这个错误:

[wsgi:error] [pid 5840:tid 828] [client 127.0.0.1:54621] import hello [wsgi:error] [pid 5840:tid 828] [client 127.0.0.1:54621] ImportError: No module named hello

你有什么想法吗?我做错了什么吗?

编辑:

index.py
__init__.py
modules/
  hello.py
  HelloWorld.py
  moduletest.py
  User/
    Users.py

index.py 中,将 import hello 替换为 from modules import hello - Cajuu'
我在这个问题上遇到了错误:ImportError: No module named modules - Run
1
尝试在您的“模块”目录中添加一个“init.py”文件。 - Cajuu'
请参阅在Python中导入包 - PM 2Ring
4个回答

7
modules/目录中应该有一个__init__.py文件,告诉Pythonmodules是一个。它可以是一个空文件。
如果你愿意,你可以把这个放到__init__.py中,以简化导入包的模块:
__all__ = ['hello', 'HelloWorld', 'moduletest']

来自导入包中的*

当用户写下 sound.effects import * 时会发生什么呢? 理想情况下,希望它会去文件系统中查找该包中存在哪些子模块,并将它们全部导入。 这可能需要很长时间,并且导入子模块可能会产生不希望发生的副作用,这些副作用应该只在显式导入子模块时发生。

唯一的解决方案是由包的作者提供一个明确的包索引。导入语句使用以下约定:如果包的 __init__.py 代码定义了一个名为 __all__ 的列表,则认为这是应该在遇到 from package import * 时导入的模块名称列表。在发布新版本的包时,包作者负责保持此列表最新。如果包作者不认为从他们的包中导入 * 有用,他们也可以决定不支持它。


modules/__init__.py文件中,我应该放什么内容? - Run
@teelou:你不需要放任何东西。就像我说的,它可以是一个空文件。但是你可以在里面放一些东西,使导入你的包模块更容易。我会在几分钟内添加更多信息到我的答案中。 - PM 2Ring
1
@teelou:我刚刚看了你的编辑。在“ modules/User/”中,你还需要一个“init.py”。请查看我在先前评论中链接的代码,因为它的结构类似于你的项目结构。 - PM 2Ring
@PM2Ring 谢谢。实际上,(@)plaes 指出的关键是要设置模块的路径... - Run
1
@teelou:当然可以。你的包的顶级目录需要在Python路径中。所以,如果它不在你的正常Python路径中,那么你需要显式地添加它。但是你不需要担心将你的包的子目录添加到Python路径中——__init__.py会让Python知道如何找到它们,一旦它找到了顶级目录(从路径信息中)并意识到它是一个包(来自该顶级目录中的__init__.py)。 - PM 2Ring
显示剩余2条评论

3

您需要在.wsgi文件中设置应用程序的路径,在您的情况下似乎是index.py

import sys

path = '/full/path/to/app'
if path not in sys.path:
   sys.path.insert(0, path)

这实际上解决了我的问题。虽然可能有更好的方法来获取路径:os.path.split(__file__)[0] - orblivion
1
话虽如此,直接将 Python 路径传递给 WSGI 可能更好。--python-path /full/path/to/app - orblivion

2

当我尝试这样做时,在<Directory>部分中需要使用相同的组名WSGIProcessGroup example - Bob Stein

0
在你的代码 hello.py 中只包含一个方法,如果你将它封装在一个类中,那么它就会被视为一个模块。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接