【问题标题】:Python: 'ModuleNotFoundError' when trying to import module from another coding .py filePython:尝试从另一个编码 .py 文件导入模块时出现“ModuleNotFoundError”
【发布时间】:2020-03-18 02:47:22
【问题描述】:

我在 MacBook Pro(13 英寸,2016 年,两个 Thunderbolt 3 端口)上使用 Python 3.8.3

我目前正在建立一个在线聊天,这是我的 person.py 代码:

class Person:

    """
    Represents a person, hold name, socket client and client addr
    """
    def __init__(self, addr, client):
        self.addr = addr
        self.client = client
        self.name = None

    def set_name(self, name):
        self.name = name

    def __repr__(self):
        return f"Person({self.addr}, {self.name})"

这是我的 server.py 编码:

from threading import Thread
import time
from person import Person

# GLOBAL CONSTANTS
HOST = 'localhost'
PORT = 5500
ADDR = (HOST, PORT)
MAX_CONNECTIONS = 10
BUFSIZ = 512

# GLOBAL VARIABLES
persons = []
SERVER = socket(AF_INET, SOCK_STREAM)
SERVER.bind(ADDR)  # set up server

def broadcast(msg, name):
    """
    send new messages to all clients
    :param msg: bytes["utf8"]
    :param name: str
    :return:
    """
    for person in persons:
        client = person.client
        client.send(bytes(name, "utf8") + msg)


def client_communication(person):
    """
    Thread to handle all messages from client
    :param person: Person
    :return: None
    """
    client = person.client

    # get persons name
    name = client.recv(BUFSIZ).decode("utf8")
    person.set_name(name)
    msg = bytes(f"{name} has joined the chat!", "utf8")
    broadcast(msg, "")  # broadcast welcome message


    while True:
        try:
            msg = client.recv(BUFSIZ)

            if msg == bytes("{quit}", "utf8"):
                client.close()
                persons.remove(person)
                broadcast(f"{name} has left the chat...", "")
                print(f"[DISCONNECTED] {name} disconnected")
                break
            else:
                broadcast(msg, name+": ")
                print(f"{name}: ", msg.decode("utf8"))

        except Exception as e:
            print("[EXCEPTION]", e)
            break


def wait_for_connection():
    """
    Wait for connetion from new clients, start new thread once connected
    :param SERVER: SOCKET
    :return: None
    """
    run = True
    while run:
        try:
            client, addr = SERVER.accept()
            person = Person(addr, client)
            persons.append(person)
            print(f"[CONNECTION] {addr} connected to the server at {time.time()}")
            Thread(target=client_communication, args=(person,)).start()
        except Exception as e:
            print("[EXCEPTION]", e)
            run = False

    print("SERVER CRASHED")


if __name__ == "__main__":
    SERVER.listen(MAX_CONNECTIONS)  # listen for connections
    print("[STARTED] Waiting for connections...")
    ACCEPT_THREAD = Thread(target=wait_for_connection)
    ACCEPT_THREAD.start()
    ACCEPT_THREAD.join()
    SERVER.close()

问题是,每次我尝试运行程序时,它都会给我这个错误:

    from person import Person
ModuleNotFoundError: No module named 'person'

有人知道如何解决这个问题吗?

【问题讨论】:

  • person 在你的 Python 路径上吗?您运行代码的精度如何?
  • 这是一个导入问题。您需要提供两个文件位置的详细信息。
  • 1-如何查看它是否在我的 python 路径上? 2-我使用我的 python 控制台运行它。是吗?
  • 我如何提供详细信息?

标签: python python-3.x


【解决方案1】:

问题

这很可能是寻路错误。 Python 路径将在安装的 libsite-packages 文件夹中查找。它还将查看当前工作目录。因此,如果您从另一个文件夹运行一个文件但尝试导入某些内容,它将在您的运行目录中查找,而不是您正在运行的文件所在的位置。这里有两个解决这个问题的方法。

第一个解决方案

您可以使工作目录与您正在运行的文件相同。给出以下文件结构:

workingdir
+-- thecode
    |-- server.py
    +-- person.py

您拥有当前工作目录,也就是您以workingdir 运行命令的位置,因此终端可能如下所示:

workingdir % python thecode/server.py

因此,您需要将工作目录更改为 thecode。请cd thecode 到达那里。

第二种解决方案

您可以改为将文件的目录添加到 python 路径。这保存在 sys.path 中,并在每次 python 运行结束时获取。因此,最好在您的server.py 文件的开头添加路径,以便在您导入它之前person.py 在您的路径中。使用类似于以下代码的代码来执行此操作。

import sys
import os.path
sys.path.append(os.path.split(os.path.abspath(__file__))[0])

# now you may import Person.
from person import Person

前两个模块sysos 是相当标准的,它们会为您提供附加到Python 路径的工具。 os.path.abspath 获取当前文件的绝对路径,在本例中为 server.py。然后os.path.split 将获得绝对路径的尾部(所有目录)和头部(文件名)。最后追加到sys.path 允许Python 在你的文件目录中找到person.py

其他解决方案(在这种情况下可能不会使用)

您还可以创建自定义 Python 包并使用 pip 安装它。这在这种情况下不是很有用,因为导入问题只是一个文件,但是,如果您想创建一个其他人可能使用的自定义 Python 项目this Python docs article will help

最终的解决方案(诚然,我曾经这样做过,但不是最好的解决方法)是将文件放在 Python 路径中已经存在的文件夹中。在这种情况下,它可能是lib 文件夹。对我来说,运行 Python 3.8 的路径是 /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8,对于任何 Python 3.x 版本,这将是相同的,但版本被替换了。 Python 2.x 有时会有不同的位置。

【讨论】:

    猜你喜欢
    • 2021-12-05
    • 2021-07-12
    • 2019-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 2020-03-21
    • 2021-01-26
    相关资源
    最近更新 更多