ModuleNotFoundError: Nghĩa là __main__ không phải là một gói?


206

Tôi đang cố gắng để chạy một mô-đun từ bàn điều khiển. Cấu trúc của thư mục của tôi là thế này:

nhập mô tả hình ảnh ở đây

Tôi đang cố gắng chạy mô-đun p_03_using_bisection_search.py, từ problem_set_02thư mục bằng cách sử dụng:

$ python3 p_03_using_bisection_search.py

Mã bên trong p_03_using_bisection_search.pylà:

__author__ = 'm'


from .p_02_paying_debt_off_in_a_year import compute_balance_after


def compute_bounds(balance: float,
                   annual_interest_rate: float) -> (float, float):

    # there is code here, but I have omitted it to save space
    pass


def compute_lowest_payment(balance: float,
                           annual_interest_rate: float) -> float:

    # there is code here, but I have omitted it to save space
    pass    

def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(input('Enter the annual interest rate: '))

    lowest_payment = compute_lowest_payment(balance, annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

Tôi đang nhập một hàm p_02_paying_debt_off_in_a_year.pychứa mã:

__author__ = 'm'


def compute_balance(balance: float,
                    fixed_payment: float,
                    annual_interest_rate: float) -> float:

    # this is code that has been omitted
    pass


def compute_balance_after(balance: float,
                          fixed_payment: float,
                          annual_interest_rate: float,
                          months: int=12) -> float:

    # Omitted code
    pass


def compute_fixed_monthly_payment(balance: float,
                                  annual_interest_rate: float) -> float:

    # omitted code
    pass


def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(
        input('Enter the annual interest rate as a decimal: '))
    lowest_payment = compute_fixed_monthly_payment(balance,
                                                   annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

Tôi nhận được lỗi sau:

ModuleNotFoundError: No module named '__main__.p_02_paying_debt_off_in_a_year'; '__main__' is not a package

Tôi không có ý tưởng làm thế nào để giải quyết vấn đề này. Tôi đã thử thêm một __init__.pytập tin, nhưng nó vẫn không hoạt động.


3
Không phải vấn đề của bạn, nhưng tôi chỉ muốn ném nó ra khỏi đó: eval(input...có lẽ không phải là một ý tưởng tuyệt vời. Tôi chỉ phân tích nó thay vì mở ra cơ hội thực thi mã tùy ý.
Carcigenicate

2
Tôi cá là eval(input(...bit đó được đề xuất bởi 2to3. Tôi đã có nó làm điều đó với tôi ngày hôm nay. rất vui vì tôi không làm theo những gợi ý bịt mắt
ckot

Câu trả lời:


236

Chỉ cần xóa dấu chấm cho nhập tương đối và làm:

from p_02_paying_debt_off_in_a_year import compute_balance_after

56
bạn giải quyết nó Tại sao nhập tương đối không hoạt động ngay cả khi tôi thêm __init__.py?
lmiguelvargasf

23
Câu trả lời được chấp nhận là không làm việc cho tôi. Bạn có thể mở rộng câu trả lời bằng cách thêm một thiết lập ví dụ tối giản không?
Pranaas

13
Điều này hoạt động với tôi (bên trong một gói, tức là có một __init__.pytệp trống trong cùng một thư mục), mặc dù PyCharm của tôi (2018.2.4) đánh dấu đây là "Tham chiếu chưa được giải quyết" và không tự động hoàn tất quá trình nhập.
djvg

33
@djvg - Để sửa lỗi PyCharm, bạn có thể đánh dấu thư mục gốc là root nguồn
Denis Yakovlev

12
Làm việc với hàng nhập khẩu của Python đang gây phẫn nộ. Nó giống như Python 3, PyCharm và MyPy đều có tiếng cười lớn với chi phí của chúng tôi. Làm thế nào là from ..sibling_pkg.nephew import my_functionhợp lệ cho PyCharm, nhưng kết quả ValueError: attempted relative import beyond top-level packagevà MyPy Cannot find module named '.sibling_pkg.nephew'(lưu ý một "." Trong lỗi, không phải hai). Tuy nhiên, from sibling_pkg.nephew import my_functionhoạt động như dự định, không có lỗi MyPy, nhưng không gây ra lỗi PyCharm.
ubiquibacon

85

Tôi có cùng một vấn đề như bạn đã làm. Tôi nghĩ vấn đề là bạn đã sử dụng nhập tương đối in-package import. Không có __init__.pytrong thư mục của bạn. Vì vậy, chỉ cần nhập khẩu như Moses đã trả lời ở trên.

Vấn đề cốt lõi tôi nghĩ là khi bạn nhập bằng dấu chấm:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Nó tương đương với:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

trong đó __main__đề cập đến mô-đun hiện tại của bạn p_03_using_bisection_search.py.


Tóm lại, trình thông dịch không biết kiến ​​trúc thư mục của bạn.

Khi trình thông dịch vào p_03.py, tập lệnh bằng:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

p_03_using_bisection_searchkhông chứa bất kỳ mô-đun hoặc trường hợp nào được gọi p_02_paying_debt_off_in_a_year.


Vì vậy, tôi đã đưa ra một giải pháp sạch hơn mà không thay đổi các vật có giá trị môi trường python (sau khi tìm hiểu cách yêu cầu thực hiện trong nhập khẩu tương đối):

Kiến trúc chính của thư mục là:

main.py

setup.py

---problem_set_02/

------__init__.py

------p01.py

------p02.py

------p03.py

Sau đó viết vào __init__.py:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Đây __main____init__, nó chính xác đề cập đến các mô-đun problem_set_02.

Sau đó đi đến main.py:

import problem_set_02

Bạn cũng có thể viết một setup.pyđể thêm mô-đun cụ thể vào môi trường.


9

Hãy thử chạy nó như:

python3 -m p_03_using_bisection_search


2

Xin vui lòng làm theo bước dưới đây, bạn sẽ giải quyết vấn đề này. Nếu bạn đã tạo thư mục và thư mục con thì hãy làm theo các bước dưới đây và xin lưu ý tất cả thư mục phải có __init__.pyđể nó được nhận dạng là một thư mục.

  1. import sysvà chạy sys.path, bạn sẽ có thể thấy tất cả các đường dẫn đang được tìm kiếm bởi python. Bạn phải có thể xem thư mục làm việc hiện tại của mình.

  2. Bây giờ, nhập thư mục con và mô-đun tương ứng mà bạn muốn sử dụng bằng cách nhập theo lệnh này: import subdir.subdir.modulename as abcvà bây giờ bạn có thể sử dụng các phương thức trong mô-đun đó. ScreenShotforSameIssue

như bạn có thể thấy trong ảnh chụp màn hình này, tôi có một thư mục mẹ và hai thư mục con và trong thư mục con thứ hai tôi có mô-đun == CommonFunction và bạn thấy phía bên phải sau khi thực hiện sys.path Tôi có thể thấy thư mục làm việc của mình


1

Xóa dấu chấm và nhập perfect_import vào đầu tệp của bạn

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after

1

Chỉ cần sử dụng tên của thư mục chính chứa tệp .py.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.