关于python+wsgi:不能从目录导入我自己的模块?

Python + WSGI - Can't import my own modules from a directory?

我对python不熟悉,我已经研究了如何从目录/子目录导入自定义模块。比如这个和这个。

这是我的结构,

1
2
3
4
5
6
index.py
__init__.py
modules/
  hello.py
  HelloWorld.py
  moduletest.py

索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 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,

1
2
3
from modules import moduletest
from modules import hello
from modules import HelloWorld

模块/hello.py,

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

模块/helloworld.py,

1
2
3
4
5
6
7
# define a class
class HelloWorld:
    def __init__(self):
        self.message = 'Hello World from HelloWorld.py!'

    def sayHello(self):
        return self.message

模块/模块测试.py,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 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."

但是通过ApacheWSGi,我得到了这个错误,

[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

知道我做错了什么吗?

编辑:

1
2
3
4
5
6
7
8
index.py
__init__.py
modules/
  hello.py
  HelloWorld.py
  moduletest.py
  User/
    Users.py


modules/目录中应该有一个__init__.py文件,告诉python modules是一个包。它可以是空文件。

如果您愿意,可以将它放入该__init__.py中,以简化导入包的模块:

1
__all__ = ['hello', 'HelloWorld', 'moduletest']

从包导入*

Now what happens when the user writes from sound.effects import *?
Ideally, one would hope that this somehow goes out to the filesystem,
finds which submodules are present in the package, and imports them
all. This could take a long time and importing sub-modules might have
unwanted side-effects that should only happen when the sub-module is
explicitly imported.

The only solution is for the package author to provide an explicit
index of the package. The import statement uses the following
convention: if a package’s __init__.py code defines a list named
__all__, it is taken to be the list of module names that should be imported when from package import * is encountered. It is up to the
package author to keep this list up-to-date when a new version of the
package is released. Package authors may also decide not to support
it, if they don’t see a use for importing * from their package.


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

1
2
3
4
5
import sys

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


您还可以在Apache虚拟主机配置中修复此问题:

WSGIDaemonProcess example home=/path/to/mysite.com python-path=/path/to/mysite.com

有关详细信息,请参阅http://blog.dscpl.com.au/2014/09/python-module-search-path-and-modwsgi.html。


在代码中,hello.py只包含一个方法,如果将其包装在一个将被视为模块的类中。