ไม่สามารถนำเข้าโมดูลของตัวเองใน Python


141

ฉันเข้าใจว่าการอิมพอร์ตโมดูลทำงานอย่างไรใน Python (ฉันไม่เคยใช้ภาษาอื่นมาก่อน)

สมมติว่าฉันมี:

myapp/__init__.py
myapp/myapp/myapp.py
myapp/myapp/SomeObject.py
myapp/tests/TestCase.py

ตอนนี้ฉันกำลังพยายามหาบางอย่างเช่นนี้:

myapp.py
===================
from myapp import SomeObject
# stuff ...

TestCase.py
===================
from myapp import SomeObject
# some tests on SomeObject

อย่างไรก็ตามฉันทำสิ่งที่ผิดอย่างแน่นอนเนื่องจาก Python ไม่สามารถเห็นได้ว่าmyappเป็นโมดูล:

ImportError: No module named myapp

คำตอบ:


96

ในกรณีเฉพาะของคุณดูเหมือนว่าคุณกำลังพยายามนำเข้าSomeObjectจากสคริปต์ myapp.py และ TestCase.py จาก myapp.py ให้ทำ

import SomeObject

เนื่องจากมันอยู่ในโฟลเดอร์เดียวกัน สำหรับ TestCase.py ให้ทำ

from ..myapp import SomeObject

อย่างไรก็ตามวิธีนี้จะใช้ได้เฉพาะเมื่อคุณนำเข้า TestCase จากแพ็คเกจ หากคุณต้องการเรียกใช้โดยตรงpython TestCase.pyคุณจะต้องยุ่งกับเส้นทางของคุณ สามารถทำได้ภายใน Python:

import sys
sys.path.append("..")
from myapp import SomeObject

แม้ว่าโดยทั่วไปจะไม่แนะนำ

โดยทั่วไปถ้าคุณต้องการให้คนอื่นใช้แพ็คเกจ Python ของคุณคุณควรใช้distutilsเพื่อสร้างสคริปต์การติดตั้ง ด้วยวิธีนี้ทุกคนสามารถติดตั้งแพ็กเกจของคุณได้อย่างง่ายดายโดยใช้คำสั่งที่ชอบpython setup.py installและจะสามารถใช้ได้ทุกที่บนเครื่องของพวกเขา หากคุณร้ายแรงเกี่ยวกับแพคเกจที่คุณยังสามารถเพิ่มไปยังหลามแพ็คเกจดัชนีPyPI


ฉันพยายามเพียงแค่ใช้importในของฉันTestCase.pyแต่มันก็ยังทำให้ฉันมีข้อผิดพลาดเดียวกัน ฉันสมมติว่าเป็นเพราะมันอยู่ในไดเรกทอรีย่อยของ__init__.py?
n0pe

โอ้เดี๋ยวก่อนฉันคิดว่าฉันเข้าใจแล้ว หากกรณีทดสอบของฉันโทรจากแพ็คเกจฉันจะสามารถใช้from ... import ...สิทธิ์ได้หรือไม่
n0pe

1
คุณจะเฉพาะเมื่อ TestCase ถูกนำเข้าจากนอกแพ็คเกจ - ตัวอย่างเช่นถ้าฉันรันfrom myapp.tests import TestCase from a script outside myapp. If you're running python TestCase.py` ภายในโฟลเดอร์การทดสอบคุณจะไม่สามารถนำเข้าแบบสัมพัทธ์ได้
David Robinson

1
ฉันรัน "pip install -e." เพื่อติดตั้ง myapp แต่เมื่อพยายามรัน TestCase ในรหัส visual studio ฉันยังคงได้รับ "ImportError: ไม่มีโมดูลชื่อ myapp" แต่ถ้าฉันเรียกใช้ "python" จากนั้นใน python run "จาก myapp import SomeObject" มันใช้งานได้ ผมทำอะไรผิดหรือเปล่า?
dagrun

@DavidRobinson ฉันใช้วิธีที่คุณพูดถึงซึ่งแสดงให้เห็นว่าไม่มีข้อผิดพลาดหลังจากดำเนินการfrom fodername import file_name_of_my_py_codeแต่เมื่อฉันพยายามที่จะเข้าถึงวัตถุที่กำหนดไว้ในfile_name_of_my_py_code.pyนั้นบอกว่าNameError: name 'ClassName' is not defined
Kavin Raju S

44

ฟังก์ชั่นimportค้นหาไฟล์ใน PYTHONPATH ของคุณ env ตัวแปรและไดเรกทอรีท้องถิ่นของคุณ ดังนั้นคุณสามารถใส่ไฟล์ทั้งหมดในไดเรกทอรีเดียวกันหรือส่งออกพา ธ ที่พิมพ์ลงในเทอร์มินัล ::

export PYTHONPATH="$PYTHONPATH:/path_to_myapp/myapp/myapp/"

2
จากนั้นฉันจะแน่ใจได้อย่างไรว่ามันใช้ได้กับทุกคนที่จะใช้มัน? ฉันไม่ต้องการบอกให้ตั้งค่าตัวแปรสภาพแวดล้อมบางอย่างก่อนเรียกใช้
n0pe

1
ไดเรกทอรีปัจจุบันอยู่ใน pythonpath ตราบใดที่สคริปต์อยู่ในโฟลเดอร์ / ไดเรกทอรีเดียวกับที่ควรใช้งาน น่าเสียดายที่สคริปต์แต่ละตัวเหล่านี้อยู่ในไดเรกทอรีแยกกัน
JKirchartz

4
สำหรับผู้ใช้ Windows แทนที่จะเป็นexportเรา "ตั้งค่า PYTHONPATH =% PYTHONPATH%; C: \ path_to_myapp \ myapp \ myapp \ myapp \"
loves.by.Jesus

ในรหัส vs ฉันสามารถแก้ไขได้โดยการเพิ่ม PYTHONPATH Env variable ใน launch.json ของฉัน: "env": {"PYTHONPATH": "$ {workspaceFolder}"}
Michael Armitage

11

เส้นทางการส่งออกเป็นวิธีที่ดี อีกวิธีหนึ่งคือการเพิ่ม. pth ให้กับตำแหน่งแพ็กเกจไซต์ของคุณ สำหรับ mac ของฉันฉันใช้ python เก็บแพ็คเกจไซต์ไว้ใน / Library / Python ดังที่แสดงด้านล่าง

/Library/Python/2.7/site-packages

ฉันสร้างไฟล์ชื่อ Awesome.pth ที่ /Library/Python/2.7/site-packages/awesome.pth และในไฟล์ใส่พา ธ ต่อไปนี้ที่อ้างอิงโมดูลที่น่ากลัวของฉัน

/opt/awesome/custom_python_modules

1
ในกรณีที่ฉันทำงานใน windows ฉันจะทำเช่นนั้นได้อย่างไร
Nwawel A Iroume

ฉันไม่แน่ใจ. ในกรณีที่คุณใช้ windows ค้นหาซอฟต์แวร์ vm และใช้ linux หรือ - ดูคำตอบนี้เกี่ยวกับการส่งออกตัวแปรในหน้าต่าง stackoverflow.com/questions/559816/…
jmontross

นี่คือสิ่งที่ฉันต้องการ
Lee88

1
มีความสุขที่ได้ยินว่า @ Lee88 - ใช้เวลาสักครู่เพื่อคิดออกเอง :)
jmontross

9

คุณสามารถลอง

from myapp.myapp import SomeObject

เนื่องจากชื่อโครงการของคุณเหมือนกับ myapp.py ซึ่งทำให้ค้นหาเอกสารโครงการก่อน


3

ในไดเรกทอรี myapp แรกของคุณคุณสามารถเพิ่มไฟล์ setup.py และเพิ่มรหัสหลามสองตัวใน setup.py

from setuptools import setup
setup(name='myapp')

ในไดเรกทอรี myapp แรกของคุณใน commandline ใช้ pip install -e เพื่อติดตั้งแพ็คเกจ


2

pip installบน Windows 10 เป็นค่าเริ่มต้นสำหรับการติดตั้งใน 'Program Files / PythonXX / Lib / site-packages' ซึ่งเป็นไดเรกทอรีที่ต้องการสิทธิ์ระดับผู้ดูแลระบบ ดังนั้นฉันจึงแก้ไขปัญหาของฉันโดย ใช้การติดตั้ง pip ในฐานะผู้ดูแลระบบ (คุณต้องเปิดพรอมต์คำสั่งในฐานะผู้ดูแลระบบแม้ว่าคุณจะลงชื่อเข้าใช้ด้วยบัญชีผู้ดูแลระบบ) นอกจากนี้การเรียก pip จาก python นั้นปลอดภัยยิ่งขึ้น
เช่น
python -m pip install <package-name>
แทน
pip install <package-name>


0

ในกรณีของฉันมันเป็นความประหลาดใจของ Windows vs Python แม้ว่าชื่อไฟล์ของ Windows จะไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก ดังนั้นหากคุณมีStuff.pyไฟล์คุณจะต้องนำเข้าชื่อนี้ตามที่เป็นอยู่


0

คุณต้องมี

__init__.py

ในทุกโฟลเดอร์ที่มีรหัสที่คุณต้องโต้ตอบ คุณต้องระบุชื่อโฟลเดอร์บนสุดของโครงการของคุณในการนำเข้าทุกครั้งแม้ว่าไฟล์ที่คุณพยายามจะนำเข้าจะอยู่ในระดับเดียวกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.