【问题标题】:Python + WSGI - Can't import my own modules from a directory?Python + WSGI - 无法从目录中导入我自己的模块?
【发布时间】:2015-11-11 00:21:08
【问题描述】:

我是 Python 新手,我已经查看了如何从目录/子目录导入我的自定义模块。比如thisthis

这是我的结构,

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]

初始化.py,

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

模块/hello.py,

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

模块/HelloWorld.py,

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

    def sayHello(self):
        return self.message

模块/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] 导入 你好 [wsgi:error] [pid 5840:tid 828] [client 127.0.0.1:54621] ImportError: 没有名为 hello 的模块

知道我做错了什么吗?

编辑:

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

【问题讨论】:

  • index.py 中将import hello 替换为from modules import hello
  • ImportError: No module named modules 收到此错误
  • 尝试将__init__.py 文件添加到您的modules 目录

标签: python python-2.7 mod-wsgi wsgi


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    你应该在modules/ 目录中有一个__init__.py 文件来告诉Python modules 是一个package。它可以是一个空文件。

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

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

    来自Importing * From a Package

    现在当用户从sound.effects import * 写入时会发生什么? 理想情况下,人们希望这能以某种方式传递给文件系统, 查找包中存在哪些子模块,并导入它们 全部。这可能需要很长时间,并且导入子模块可能需要 只有当子模块是 显式导入。

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

    【讨论】:

    • 我应该在 modules/__init__.py 中添加什么?
    • @teelou:你不需要放任何东西。正如我所说,它可以是一个空文件。但是你可以在里面放一些东西,这样可以更容易地导入你的包模块。几分钟后,我会在我的答案中添加更多信息。
    • @teelou: FWIW, here's an example 我去年写了一个稍微复杂一点的包结构。
    • @teelou:我刚刚看到你的编辑。您还需要modules/User/ 中的__init__.py。请看一下我在之前评论中链接到的代码,因为它的结构与您的项目的结构相似。
    • @teelou:当然。你的包的顶层目录需要在你的 Python 路径中。因此,如果它不在您的正常 Python 路径中,那么您需要显式添加它。但是你不必担心将你的包的子目录添加到 Python 路径中——__init__.py 的东西会让 Python 知道如何找到它们,一旦它找到了顶级目录(来自路径信息)并意识到它是一个包(来自该顶级目录中的__init__.py)。
    【解决方案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]
    • 也就是说,将python路径传递给wsgi可能会更好。 --python-path /full/path/to/app.
    【解决方案4】:

    您也可以在 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 了解更多信息。

    【讨论】:

    • WSGIProcessGroup example(具有相同的组名)在我尝试此操作时需要 <Directory> 部分。
    猜你喜欢
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2020-02-21
    • 2018-06-21
    • 1970-01-01
    相关资源
    最近更新 更多