วิธีการนำเข้าคลาสภายในไดเรกทอรีเดียวกันหรือไดเรกทอรีย่อยได้อย่างไร


675

ฉันมีไดเรกทอรีที่เก็บไฟล์. pyทั้งหมด

bin/
   main.py
   user.py # where class User resides
   dir.py # where class Dir resides

ฉันต้องการที่จะใช้เรียนจากuser.pyและdir.pyในmain.py
ฉันจะนำเข้าคลาส Python เหล่านี้ไปยังmain.py ได้อย่างไร
นอกจากนี้ฉันจะนำเข้าคลาสได้Userอย่างไรหากuser.pyอยู่ในไดเรกทอรีย่อย

bin/
    dir.py
    main.py
    usr/
        user.py

ดูยังตอบในหลาม: นำเข้าไฟล์จากไดเรกทอรีย่อย
Trilarion

คำตอบ:


938

Python 2

ทำไฟล์ว่างที่เรียกว่า__init__.pyในไดเรกทอรีเดียวกับไฟล์ นั่นจะหมายถึง Python ว่า "ตกลงเพื่อนำเข้าจากไดเรกทอรีนี้"

จากนั้นก็ทำ ...

from user import User
from dir import Dir

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

bin/
    main.py
    classes/
        user.py
        dir.py

ดังนั้นถ้าไดเรกทอรีชื่อ "คลาส" คุณจะทำสิ่งนี้:

from classes.user import User
from classes.dir import Dir

Python 3

เหมือนก่อนหน้านี้ แต่นำหน้าชื่อโมดูลด้วย.ถ้าไม่ได้ใช้ไดเรกทอรีย่อย:

from .user import User
from .dir import Dir

14
ถ้า__init__.pyจะไม่ว่างแล้วสิ่งที่อยู่ใน__init__.pyคือสิ่งที่จะสามารถใช้ได้เมื่อคุณนำเข้าแพคเกจ (และสิ่งที่ไม่นำเข้ามา__init__.pyจะไม่สามารถใช้ได้เลย)
เหลืองอำพัน

23
เหตุใดจึงต้องมี__init__.pyไฟล์ทั้งหมด ถ้าฉันใส่ทั้งสามไฟล์ในไดเรกทอรีเดียวกันและเรียกใช้main.pyก็สามารถทำได้importจากอีกสองโมดูลที่ไม่มีมัน ฉันพลาดอะไรไป
martineau

30
เพราะนั่นคือวิธีที่ Python ระบุไดเรกทอรีที่คุณได้รับอนุญาตให้นำเข้า ไดเรกทอรีของสคริปต์ที่คุณเรียกใช้เป็นข้อยกเว้น - คุณได้รับอนุญาตให้นำเข้าจากมันเสมอ
เหลืองอำพัน

20
@nbro และแอมเบอร์: FWIW ฉันคิดว่ามีบางสิ่งบางอย่างที่เปลี่ยนแปลงไปเกี่ยวกับ__init__.pyและสามารถนำเข้าโมดูลอื่น ๆ ในไดเรกทอรีเดียวกัน โดยเฉพาะimportของโมดูลอื่น ๆ ในไดเรกทอรีเดียวกันกับ__init__.pyไฟล์ตัวเองที่ทำงานในหลาม 2.7.8 ล้มเหลวในหลาม 3.4.1 เมื่อต้องการแก้ไขฉันต้องนำหน้าแต่ละชื่อด้วยไดเรกทอรีย่อยและจุด (เช่นimport moduleจะต้องเปลี่ยนเป็นimport subdirectory.module) โชคดีที่มันยังทำงานได้ใน Python 2.7.8 หลังจากทำเช่นนี้
martineau

4
ฉันสามารถยืนยันได้ว่าวิธีนี้ไม่สามารถใช้งานได้อีกต่อไป คุณอาจต้องการแก้ไขแก้ไขหรือลบทิ้งทันที
Luís de Sousa

137

ฉันเพิ่งเรียนรู้ (จากคำติชมของมาร์ติโน ) ว่าเพื่อนำเข้าคลาสจากไฟล์ในไดเรกทอรีเดียวกันตอนนี้คุณจะเขียนใน Python 3:

from .user import User
from .dir import Dir

8
ถ้าฉันลองนี้ไม่ฉันได้รับข้อผิดพลาดต่อไปนี้ValueError: Attempted relative import in non-packageแต่ข้อผิดพลาดหายไปเมื่อฉันเปลี่ยนเป็นfrom user import User
Korpel

ฉันใช้จาก. fileloader นำเข้าและรับ ImportError: ไม่สามารถนำเข้าชื่อ 'Fileloader'
Frikster

3
@Korpel: ติดตามการอภิปรายในstackoverflow.com/questions/11536764/ …ฉันรู้ว่าการทำงานการนำเข้าที่ได้รับข้างต้นนั้นขึ้นอยู่กับหรือไม่ขึ้นอยู่กับ: [1] วิธีที่สคริปต์ของคุณถูกเรียกใช้ (เป็นแพคเกจหรือไม่) [2] เส้นทางการทำงานจริงคือเมื่อคุณเรียกใช้งาน [3] วิธีที่ตัวแปรของสภาพแวดล้อมการทำงานของคุณถูกเติมข้อมูล
ecp

@Korpel: ฉันสังเกตเห็นว่า ก่อนชื่อโมดูลจำเป็นต้องใช้เมื่อมีไฟล์init .py อยู่เท่านั้นหากไม่ใช่ สามารถ / ต้องถูกละเว้น
MUG4N

39

ในmain.py:

from user import Class

โดยที่Classเป็นชื่อของคลาสที่คุณต้องการนำเข้า

หากคุณต้องการเรียกวิธีการClassคุณสามารถเรียกได้โดยใช้:

Class.method

โปรดทราบว่าควรมี__init__.pyไฟล์ว่างในไดเรกทอรีเดียวกัน


1
คุณจะทำอย่างไรถ้าโมดูลที่คุณพยายามนำเข้าไม่มีคลาส? ฟังก์ชั่นดิบๆเหรอ? ใน python 2 สิ่งที่ฉันต้องทำคือ 'import module' ใช้งานไม่ได้กับ python 3 และ 'นำเข้า. โมดูล'
Frikster

2
งานนี้ใน python3 __init__.pyหลังจากที่ถูกลบ
engineforce

13

คุณสามารถนำเข้าโมดูลและเข้าถึงชื่อได้หากคุณไม่ต้องการผสมผสานฟังก์ชั่นและคลาสเข้ากับของคุณ

import util # imports util.py

util.clean()
util.setup(4)

หรือคุณสามารถนำเข้าฟังก์ชั่นและชั้นเรียนไปยังรหัสของคุณ

from util import clean, setup
clean()
setup(4)

คุณสามารถใช้ wildchar * เพื่อนำเข้าทุกสิ่งในโมดูลนั้นไปยังรหัสของคุณ

from util import *
clean()
setup(4)

10

ใน python3, __init__.pyคือไม่จำเป็นอีกต่อไป หากไดเรกทอรีปัจจุบันของคอนโซลเป็นไดเรกทอรีที่ตั้งสคริปต์ของหลามทุกอย่างทำงานได้ดี

import user

อย่างไรก็ตามสิ่งนี้จะไม่ทำงานหากถูกเรียกจากไดเรกทอรีอื่นซึ่งไม่มีuser.pyอยู่
ในกรณีนั้นให้ใช้

from . import user

วิธีนี้ใช้ได้แม้ว่าคุณต้องการนำเข้าไฟล์ทั้งหมดแทนที่จะเป็นคลาสจากที่นั่น


2
ฉันใช้ pylint กับรหัส vs และมีปัญหากับการนำเข้าไดเรกทอรีเดียวกันถูกตั้งค่าสถานะเป็นข้อผิดพลาดเสมอ ( import userถูกขีดเส้นใต้ด้วยสีแดง); เปลี่ยนเป็นการนำเข้าแบบสัมพัทธ์ ( from . import user) และส่วนท้ายไม่ได้ตั้งค่าสถานะอีกต่อไป
rbatt

9

เพื่อให้เข้าใจง่ายขึ้น:

ขั้นตอนที่ 1: ให้ไปที่ไดเรกทอรีเดียวซึ่งทุกอย่างจะถูกรวมไว้

$ cd /var/tmp

ขั้นตอนที่ 2: ตอนนี้ให้สร้างไฟล์ class1.py ซึ่งมีชื่อคลาส Class1 ด้วยรหัสบางส่วน

$ cat > class1.py <<\EOF
class Class1:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class1 OK]: " + ENDC
EOF

ขั้นตอนที่ 3: ตอนนี้ให้สร้างไฟล์ class2.py ซึ่งมีชื่อคลาส Class2 ด้วยรหัสบางส่วน

$ cat > class2.py <<\EOF
class Class2:
    OKBLUE = '\033[94m'
    ENDC = '\033[0m'
    OK = OKBLUE + "[Class2 OK]: " + ENDC
EOF

ขั้นตอนที่ 4: ตอนนี้ให้สร้าง main.py หนึ่งอันซึ่งจะทำงานหนึ่งครั้งเพื่อใช้ Class1 และ Class2 จาก 2 ไฟล์ที่แตกต่างกัน

$ cat > main.py <<\EOF
"""this is how we are actually calling class1.py and  from that file loading Class1"""
from class1 import Class1 
"""this is how we are actually calling class2.py and  from that file loading Class2"""
from class2 import Class2

print Class1.OK
print Class2.OK
EOF

ขั้นตอนที่ 5: เรียกใช้โปรแกรม

$ python main.py

ผลลัพธ์จะเป็น

[Class1 OK]: 
[Class2 OK]:

4
และจะเกิดอะไรขึ้นถ้าสิ่งนี้ใช้ไม่ได้และ main.py ไม่สามารถอ่าน class1 หรือ class2 ได้ ... เราจะพลาดอะไรไป
darkgaze

6

Python 3


directoryเดียวกัน

ไฟล์นำเข้า:log.py

ชั้นนำเข้า: SampleApp().

import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()

หรือ

basicไดเรกทอรี

log.pyนำเข้าในไฟล์:

ชั้นนำเข้า: SampleApp().

from basic import log
if __name__ == "__main__":
    app = log.SampleApp()
    app.mainloop()

5
from user import User 
from dir import Dir 

สิ่งนี้ใช้ได้สำหรับฉันโดยไม่ต้องมีไฟล์init .py สำหรับทั้ง Python 2.7 และ Python 3.6
imsrgadich

1
@imsrgadich ทำงานได้ตราบใดที่คุณใช้งาน python ในไดเรกทอรีที่มีไฟล์อยู่ นี่เป็นข้อยกเว้น ดูความคิดเห็นนี้
Ciprian Tomoiagă

5

หาก user.py และ dir.py ไม่รวมคลาส

from .user import User
from .dir import Dir

ไม่ทำงาน. คุณควรนำเข้าเป็น

from . import user
from . import dir

0

ฉันไม่แน่ใจว่าทำไมงานนี้ แต่ใช้ Pycharm build from file_in_same_dir import class_name

IDE บ่นเกี่ยวกับมัน แต่ดูเหมือนว่ามันยังทำงานอยู่ ฉันใช้ Python 3.7


-2

สั้นเกินไปสร้างไฟล์__init__.pyเป็นไดเรกทอรีคลาสแล้วนำเข้าสู่สคริปต์ของคุณดังต่อไปนี้ (นำเข้าทุกกรณี)

from classes.myscript import *

นำเข้าคลาสที่เลือกเท่านั้น

from classes.myscript import User
from classes.myscript import Dir

4
การนำเข้า Wildcard เท่าที่เห็นในคำตอบนี้โดยทั่วไปถือว่าเป็นรูปแบบที่ไม่ดีตามที่อธิบายในPEP 8
V02460

-3

เพื่อนำเข้าจากไดเรกทอรีเดียวกัน

from . import the_file_you_want_to_import 

เพื่อนำเข้าจากไดเรกทอรีย่อยไดเรกทอรีควรมี

init .py

ไฟล์อื่นที่ไม่ใช่ไฟล์ของคุณ

จากไดเรกทอรีนำเข้า your_file


3
ฉันไม่คิดว่าคำตอบนี้จะเพิ่มสิ่งใด ๆ ที่คำตอบอื่นไม่ได้และยังไม่ได้สรุปอย่างครอบคลุมของคำตอบอื่น ๆ ดังนั้นฉันจึงสงสัยว่าทำไมคุณถึงเขียน
lucidbrot

-3

Python3

ใช้

from .user import User inside dir.py file

และ

use from class.dir import Dir inside main.py
or from class.usr import User inside main.py

ชอบมาก


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