วิธีการนำเข้าไฟล์ Python อื่น ๆ


798

ฉันจะนำเข้าไฟล์อื่นใน Python ได้อย่างไร

  1. ฉันจะนำเข้าไฟล์ไพ ธ อนได้import file.pyอย่างไร?
  2. ฉันจะนำเข้าโฟลเดอร์แทนไฟล์เฉพาะได้อย่างไร
  3. ฉันต้องการโหลดไฟล์ Python แบบไดนามิกที่รันไทม์โดยยึดตามการป้อนข้อมูลของผู้ใช้
  4. ฉันต้องการทราบวิธีการโหลดเพียงส่วนเดียวจากไฟล์

ตัวอย่างเช่นในmain.pyฉันมี:

from extra import * 

แม้ว่าสิ่งนี้จะให้คำจำกัดความทั้งหมดแก่ฉันในextra.pyเมื่อบางทีสิ่งที่ฉันต้องการคือนิยามเดียว

def gap():
    print
    print

ฉันจะทำอะไรเพิ่มimportคำสั่งที่เพิ่งได้รับgapจากextra.py?


ดูเพิ่มเติมที่: stackoverflow.com/questions/8663076/…
dreftymac

คำตอบ:


443

importlibถูกเพิ่มใน Python 3 เพื่อนำเข้าโมดูลโดยทางโปรแกรม มันเป็นเพียงเสื้อคลุมรอบ__import__ดูเอกสาร

import importlib

moduleName = input('Enter module name:')
importlib.import_module(moduleName)

หมายเหตุ: ส่วนขยายจะถูกลบออกจาก.py moduleNameฟังก์ชั่นยังกำหนดpackageอาร์กิวเมนต์สำหรับการนำเข้าที่เกี่ยวข้อง


อัปเดต: คำตอบด้านล่างล้าสมัยแล้ว ใช้ทางเลือกใหม่ล่าสุดด้านบน

  1. เพียงแค่import fileไม่มีส่วนขยาย '.py'

  2. __init__.pyคุณสามารถทำเครื่องหมายโฟลเดอร์เป็นแพ็กเกจโดยการเพิ่มไฟล์ที่ว่างเปล่าชื่อ

  3. คุณสามารถใช้__import__ฟังก์ชั่น ใช้ชื่อโมดูลเป็นสตริง (อีกครั้ง: ชื่อโมดูลที่ไม่มีส่วนขยาย '.py')

    pmName = input('Enter module name:')
    pm = __import__(pmName)
    print(dir(pm))

    พิมพ์help(__import__)รายละเอียดเพิ่มเติม


7
หากคุณเพิ่มลงimport filenameในinit .py คุณสามารถนำเข้าโมดูลโดยตรงเป็นชื่อโฟลเดอร์
CornSmith

9
จากhelp(__import__):Because this function is meant for use by the Python interpreter and not for general use it is better to use importlib.import_module() to programmatically import a module.
Tadhg McDonald-Jensen

6
ถ้าไม่ใช่แพ็คเกจ แต่เป็นไฟล์สคริปต์
Jonathan

3
สำหรับการนำเข้าไฟล์สคริปต์ในพา ธ เดียวกัน (อาจใช้กับไฟล์สคริปต์ในพา ธ การค้นหา Python ได้) ใช้import filenamenoextงานได้ดีสำหรับฉันด้วย Python 3.4.8
Alex Hall

7
มันยังคงถูกต้องในปี 2019? มันคือ python3 หรือ 2
Sandburg

1030

มีหลายวิธีในการนำเข้าไฟล์ไพ ธ อนด้วยข้อดีข้อเสีย

อย่ารีบเลือกกลยุทธ์การนำเข้าครั้งแรกที่เหมาะกับคุณไม่งั้นคุณจะต้องเขียน codebase อีกครั้งในภายหลังเมื่อคุณพบว่ามันไม่ตรงกับความต้องการของคุณ

ฉันจะเริ่มอธิบายตัวอย่างที่ง่ายที่สุด # 1 จากนั้นฉันจะย้ายไปยังตัวอย่างที่เป็นมืออาชีพและแข็งแกร่งที่สุด # 7

ตัวอย่างที่ 1 นำเข้าโมดูลหลามด้วยตัวแปลหลาม:

  1. วางไว้ใน /home/el/foo/fox.py:

    def what_does_the_fox_say():
      print("vixens cry")
  2. เข้าสู่ล่ามหลาม:

    el@apollo:/home/el/foo$ python
    Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
    >>> import fox
    >>> fox.what_does_the_fox_say()
    vixens cry
    >>> 

    คุณนำเข้าสุนัขจิ้งจอกผ่านล่ามไพ ธ อนเรียกใช้ฟังก์ชันไพ ธ อนwhat_does_the_fox_say()จากภายใน fox.py

ตัวอย่างที่ 2 ใช้execfileหรือ ( execใน Python 3 ) ในสคริปต์เพื่อเรียกใช้งานไฟล์ python อื่น ๆ แทน:

  1. วางไว้ใน /home/el/foo2/mylib.py:

    def moobar():
      print("hi")
  2. วางไว้ใน /home/el/foo2/main.py:

    execfile("/home/el/foo2/mylib.py")
    moobar()
  3. เรียกใช้ไฟล์:

    el@apollo:/home/el/foo$ python main.py
    hi

    ฟังก์ชั่น moobar ถูกนำเข้าจาก mylib.py และให้บริการใน main.py

ตัวอย่างที่ 3 ฟังก์ชั่นใช้จาก ... นำเข้า ...

  1. วางไว้ใน /home/el/foo3/chekov.py:

    def question():
      print "where are the nuclear wessels?"
  2. วางไว้ใน /home/el/foo3/main.py:

    from chekov import question
    question()
  3. เรียกใช้ดังนี้:

    el@apollo:/home/el/foo3$ python main.py 
    where are the nuclear wessels?

    หากคุณกำหนดฟังก์ชั่นอื่น ๆ ใน chekov.py จะไม่สามารถใช้งานได้ยกเว้นคุณ import *

ตัวอย่างที่ 4 นำเข้า riaa.py หากอยู่ในตำแหน่งไฟล์อื่นที่นำเข้ามา

  1. วางไว้ใน /home/el/foo4/stuff/riaa.py:

    def watchout():
      print "computers are transforming into a noose and a yoke for humans"
  2. วางไว้ใน /home/el/foo4/main.py:

    import sys 
    import os
    sys.path.append(os.path.abspath("/home/el/foo4/stuff"))
    from riaa import *
    watchout()
  3. เรียกใช้:

    el@apollo:/home/el/foo4$ python main.py 
    computers are transforming into a noose and a yoke for humans

    ที่นำเข้าทุกสิ่งในไฟล์ต่างประเทศจากไดเรกทอรีอื่น

ตัวอย่างที่ 5 ใช้ os.system("python yourfile.py")

import os
os.system("python yourfile.py")

ตัวอย่างที่ 6 นำเข้าไฟล์ของคุณผ่าน piggybacking python startuphook:

อัปเดต:ตัวอย่างนี้ใช้เพื่อทำงานกับทั้ง python2 และ 3 แต่ตอนนี้ใช้ได้กับ python2 เท่านั้น python3 กำจัดชุดคุณลักษณะการเริ่มต้นใช้งานผู้ใช้นี้เนื่องจากมันถูกทารุณกรรมโดยผู้เขียนไลบรารีหลามที่มีทักษะต่ำโดยใช้มันเพื่อใส่รหัสของพวกเขาลงในเนมสเปซส่วนกลางก่อนที่โปรแกรมทั้งหมดจะถูกกำหนดโดยผู้ใช้ หากคุณต้องการให้ python3 ทำงานได้คุณจะต้องมีความคิดสร้างสรรค์มากขึ้น ถ้าฉันบอกคุณถึงวิธีการทำผู้พัฒนาหลามจะปิดการใช้งานคุณลักษณะที่กำหนดไว้เช่นกันดังนั้นคุณจะต้องรับผิดชอบเอง

ดู: https://docs.python.org/2/library/user.html

ใส่รหัสนี้ในไดเรกทอรีบ้านของคุณ ~/.pythonrc.py

class secretclass:
    def secretmessage(cls, myarg):
        return myarg + " is if.. up in the sky, the sky"
    secretmessage = classmethod( secretmessage )

    def skycake(cls):
        return "cookie and sky pie people can't go up and "
    skycake = classmethod( skycake )

ใส่รหัสนี้ใน main.py ของคุณ (สามารถอยู่ได้ทุกที่):

import user
msg = "The only way skycake tates good" 
msg = user.secretclass.secretmessage(msg)
msg += user.secretclass.skycake()
print(msg + " have the sky pie! SKYCAKE!")

เรียกใช้คุณควรได้รับสิ่งนี้:

$ python main.py
The only way skycake tates good is if.. up in the sky, 
the skycookie and sky pie people can't go up and  have the sky pie! 
SKYCAKE!

หากคุณได้รับข้อผิดพลาดที่นี่: ModuleNotFoundError: No module named 'user'หมายความว่าคุณใช้ python3 การเริ่มต้นใช้งานจะถูกปิดใช้งานที่นั่น

เครดิตสำหรับเรื่องตลกนี้ไปที่: https://github.com/docwhat/homedir-examples/blob/master/python-commandline/.pythonrc.py ส่งตามเรือของคุณ

ตัวอย่างที่ 7, ทนทานที่สุด: นำเข้าไฟล์ในหลามด้วยคำสั่งนำเข้าเปล่า:

  1. สร้างไดเรกทอรีใหม่ /home/el/foo5/
  2. สร้างไดเรกทอรีใหม่ /home/el/foo5/herp
  3. ทำไฟล์ว่างชื่อ__init__.pyภายใต้ herp:

    el@apollo:/home/el/foo5/herp$ touch __init__.py
    el@apollo:/home/el/foo5/herp$ ls
    __init__.py
  4. สร้างไดเรกทอรีใหม่ / home / el / foo5 / herp / derp

  5. ภายใต้ derp ให้สร้าง__init__.pyไฟล์อื่น:

    el@apollo:/home/el/foo5/herp/derp$ touch __init__.py
    el@apollo:/home/el/foo5/herp/derp$ ls
    __init__.py
  6. ภายใต้ / home / el / foo5 / herp / derp สร้างไฟล์ใหม่ที่เรียกว่าyolo.pyใส่ไว้ในนั้น:

    def skycake():
      print "SkyCake evolves to stay just beyond the cognitive reach of " +
      "the bulk of men. SKYCAKE!!"
  7. ช่วงเวลาแห่งความจริงสร้างไฟล์ใหม่/home/el/foo5/main.pyใส่สิ่งนี้ไว้ในนั้น

    from herp.derp.yolo import skycake
    skycake()
  8. เรียกใช้:

    el@apollo:/home/el/foo5$ python main.py
    SkyCake evolves to stay just beyond the cognitive reach of the bulk 
    of men. SKYCAKE!!

    __init__.pyไฟล์ที่ว่างเปล่าสื่อสารกับล่ามไพ ธ อนที่นักพัฒนาตั้งใจที่จะใช้ไดเรกทอรีนี้เป็นแพ็คเกจที่นำเข้าได้

หากคุณต้องการดูโพสต์ของฉันเกี่ยวกับวิธีรวมไฟล์. py ทั้งหมดในไดเรกทอรีให้ดูที่นี่: https://stackoverflow.com/a/20753073/445131


6
นอกจากนี้คุณยังควรเพิ่มตัวอย่างที่ 6: __import__(py_file_name)การใช้ คู่มือที่น่าทึ่งอยู่แล้ว
oriadam

4
ทุกครั้งที่ฉันมีปัญหาการนำเข้าฉันจะสิ้นสุดที่คำถามนี้และสามารถแก้ปัญหาของฉันได้เสมอ ถ้าฉันสามารถลงคะแนนในแต่ละครั้งที่คุณช่วยฉันฉันจะ
dgBP

4
อะไรคือความแตกต่างที่ยิ่งใหญ่ระหว่างสิ่งเหล่านี้และทำไมจึงเป็นสิ่งที่ดีกว่าสิ่งอื่นใด ตัวอย่างเช่น 5 คุณเขียน "นำเข้าไฟล์ในไพ ธ อนด้วยคำสั่ง bare import" แต่คุณใช้คำสั่ง import (เปล่า?) ในตัวอย่างที่ 1, 3 และ 4 ใช่ไหม?
HelloGoodbye

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

2
ฉันต้องการเน้นว่าแม้ว่าคุณจะทำงานบน Windows การนำเข้าจะต้องตรงตามตัวพิมพ์ใหญ่ - เล็ก ดังนั้นคุณไม่สามารถมีModule.pyและมีในโมดูลนำ
radato

66

ในการนำเข้าไฟล์ Python ที่เจาะจงที่ 'runtime' ด้วยชื่อที่รู้จัก:

import os
import sys

...

scriptpath = "../Test/"

# Add the directory containing your module to the Python path (wants absolute paths)
sys.path.append(os.path.abspath(scriptpath))

# Do the import
import MyModule

เพื่อนของฉันตรวจสอบวันนี้โดยไม่มีโชค - ดูเหมือนว่าชื่อไฟล์ไม่ควรอยู่ที่นั่น เขาใช้ไฟล์โลคัลในไดเรกทอรีหลักและ "./" ทำงานในตอนท้ายราวกับว่าไดเรกทอรีหลัก (.. ) ปัญหาการแก้ไขในโพสต์ถูกปฏิเสธ - อาจเข้าใจผิด sys.path พิมพ์และเปรียบเทียบบันทึกถ้าคุณไม่แน่ใจว่า ... (?)
ทอม

29

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

from root.parent.folder.file import variable, class, whatever


15
ถ้าฉันต้องการเส้นทางญาติ
domih

21

นำเข้าเอกสาร .. - ลิงก์สำหรับการอ้างอิง

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

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

mydir/spam/__init__.py
mydir/spam/module.py
import spam.module
or
from spam import module

19

กรณีแรก: คุณต้องการนำเข้าไฟล์A.pyในไฟล์B.pyทั้งสองไฟล์อยู่ในโฟลเดอร์เดียวกันเช่นนี้

. 
├── A.py 
└── B.py

คุณสามารถทำได้ในไฟล์B.py:

import A

หรือ

from A import *

หรือ

from A import THINGS_YOU_WANT_TO_IMPORT_IN_A

จากนั้นคุณจะสามารถใช้ฟังก์ชั่นทั้งหมดของไฟล์A.pyในไฟล์B.py


กรณีที่สอง: คุณต้องการนำเข้าไฟล์folder/A.pyในไฟล์B.pyทั้งสองไฟล์ไม่ได้อยู่ในโฟลเดอร์เดียวกันเช่นนี้

.
├── B.py
└── folder
     └── A.py

คุณสามารถทำได้ในไฟล์ B:

import folder.A

หรือ

from folder.A import *

หรือ

from folder.A import THINGS_YOU_WANT_TO_IMPORT_IN_A

จากนั้นคุณจะสามารถใช้ฟังก์ชั่นทั้งหมดของไฟล์A.pyในไฟล์B.py


สรุป: ในกรณีแรกไฟล์A.pyเป็นโมดูลที่คุณนำเข้าในแฟ้มคุณใช้ไวยากรณ์B.py import module_nameในกรณีที่สองfolderเป็นแพคเกจที่มีโมดูลคุณใช้ไวยากรณ์A.pyimport package_name.module_name

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับแพ็คเกจและโมดูลศึกษาจากลิงค์นี้


ฉันลองด้วยความหลากหลายเล็กน้อยและใช้งานได้ from folder_a.script import *Script.py อยู่ภายใต้โฟลเดอร์ a
Justin

+1 นี่คือสิ่งที่ฉันกำลังมองหา ไม่เข้าใจคำตอบอื่น ๆ แต่คุณอธิบายโดยใช้ไดเรกทอรี
Black Thunder

ถ้าฉันต้องการนำเข้าไฟล์ py ที่อยู่ในไดเรกทอรีหลัก
bytedev

1
@bytedev เพิ่มimport sysและsys.path.append("..")ไปยังจุดเริ่มต้นของไฟล์ ตามนี้: stackoverflow.com/a/48341902/6057480 ผ่านการทดสอบทำงานอย่างสมบูรณ์หลังจากทำเช่นนี้คุณจะสามารถนำเข้าไฟล์ py ในไดเรกทอรีหลักและยังคงสามารถนำเข้าไฟล์ py ในไดเรกทอรีและไดเรกทอรีย่อยเดียวกันได้
Bohao LI

17
from file import function_name  ######## Importing specific function
function_name()                 ######## Calling function

และ

import file              ######## Importing whole package
file.function1_name()    ######## Calling function
file.function2_name()    ######## Calling function

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


9

หากฟังก์ชั่นที่กำหนดอยู่ในไฟล์x.py:

def greet():
    print('Hello! How are you?')

ในไฟล์ที่คุณกำลังนำเข้าฟังก์ชั่นเขียนสิ่งนี้:

from x import greet

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


7

วิธีที่ดีที่สุดที่จะนำเข้าไฟล์ .py __init__.pyจะโดยวิธีการของ สิ่งที่ง่ายที่สุดที่จะทำคือสร้างไฟล์ว่างที่มีชื่อ__init__.pyในไดเรกทอรีเดียวกับไฟล์ your.py ที่ตั้ง

โพสต์นี้โดย Mike Grouchy เป็นคำอธิบายที่ยอดเยี่ยมเกี่ยวกับ__init__.pyการใช้การทำการนำเข้าและการตั้งค่าแพ็คเกจหลาม


1
@GhostCat ฉันได้อัปเดตการตอบสนองของฉัน ขอบคุณสำหรับลิงค์ "มันจะดีกว่า"
สูงสุด

และเข้าใจว่าไม่ใช่ทุกคนที่อาศัยอยู่ในเขตเวลาของคุณ
GhostCat

4
คุณควรโพสต์เนื้อหาของโพสต์ของ Mike Grouchy โดยเฉพาะตั้งแต่ลิงค์ตอนนี้ 404 web.archive.org/web/20190309045451/https://mikegrouchy.com/blog/…
qwr

6

วิธีที่ฉันนำเข้าคือการนำเข้าไฟล์และใช้ชวเลขของชื่อ

import DoStuff.py as DS
DS.main()

อย่าลืมว่าไฟล์นำเข้าของคุณจะต้องตั้งชื่อด้วยนามสกุล. py


3
จะไม่import DoStuff.py as DSพยายามนำเข้าpyจากDoStuffหรือ
Benj

5

ฉันต้องการที่จะเพิ่มบันทึกนี้ฉันไม่ชัดเจนมากที่อื่น; ภายในโมดูล / แพ็กเกจเมื่อโหลดจากไฟล์ชื่อโมดูล / mymoduleแพ็กเกจที่จะต้องนำหน้าด้วย ลองนึกภาพmymoduleการจัดวางแบบนี้:

/main.py
/mymodule
    /__init__.py
    /somefile.py
    /otherstuff.py

เมื่อโหลดsomefile.py/ otherstuff.pyจาก__init__.pyเนื้อหาควรมีลักษณะดังนี้:

from mymodule.somefile import somefunc
from mymodule.otherstuff import otherfunc

2

ในกรณีที่โมดูลที่คุณต้องการนำเข้าไม่ได้อยู่ในไดเรกทอรีย่อยให้ลองทำสิ่งต่อไปนี้และเรียกใช้app.pyจากไดเรกทอรีหลักทั่วไปที่ลึกที่สุด:

โครงสร้างไดเรกทอรี:

/path/to/common_dir/module/file.py
/path/to/common_dir/application/app.py
/path/to/common_dir/application/subpath/config.json

ในapp.pyผนวกพา ธ ของไคลเอ็นต์ไปยัง sys.path:

import os, sys, inspect

sys.path.append(os.getcwd())
from module.file import MyClass
instance = MyClass()

ตัวเลือก (ถ้าคุณโหลดเช่นตั้งค่า) (ตรวจสอบว่าเป็นอุปกรณ์ที่มีประสิทธิภาพที่สุดสำหรับกรณีการใช้งานของฉัน)

# Get dirname from inspect module
filename = inspect.getframeinfo(inspect.currentframe()).filename
dirname = os.path.dirname(os.path.abspath(filename))
MY_CONFIG = os.path.join(dirname, "subpath/config.json")

วิ่ง

user@host:/path/to/common_dir$ python3 application/app.py

วิธีนี้ใช้ได้กับฉันเช่นเดียวกับ PyCharm


2

มีหลายวิธีในการรวมสคริปต์ python ของคุณด้วยชื่อ abc.py

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

นำเข้า abc

  1. เช่นถ้าไฟล์หลามของคุณอยู่ในโฟลเดอร์ Windows โฟลเดอร์ Windows มีอยู่ในตำแหน่งเดียวกับที่สคริปต์ python ของคุณเรียกใช้

จากการนำเข้าโฟลเดอร์ abc

  1. ใส่สคริปต์ abc.py ไว้ภายใน internal_folder ซึ่งมีอยู่ในโฟลเดอร์

จาก folder.internal_folder import abc

  1. ตามที่ James ตอบไว้ข้างต้นในกรณีที่ไฟล์ของคุณอยู่ในตำแหน่งที่แน่นอน

import os
import sys
scriptpath = "../Test/MyModule.py"
sys.path.append (os.path.abspath (scriptpath))
นำเข้า MyModule

ในกรณีที่สคริปต์ python ของคุณได้รับการอัปเดตและคุณไม่ต้องการอัปโหลดให้ใช้คำสั่งเหล่านี้เพื่อรีเฟรชอัตโนมัติ โบนัส :)

%load_ext autoreload 
%autoreload 2

1

เพียงเพื่อนำเข้าไฟล์หลามในไฟล์หลามอื่น

สมมติว่าฉันมีไฟล์helper.py python ซึ่งมีฟังก์ชั่นการแสดงผลเช่น

def display():
    print("I'm working sundar gsv")

ตอนนี้ในapp.pyคุณสามารถใช้ฟังก์ชั่นการแสดงผล

import helper
helper.display()

ผลลัพธ์,

I'm working sundar gsv

หมายเหตุ:ไม่จำเป็นต้องระบุนามสกุล. py


1

สิ่งนี้อาจฟังดูบ้า แต่คุณสามารถสร้างลิงก์สัญลักษณ์ไปยังไฟล์ที่คุณต้องการนำเข้าได้หากคุณเพิ่งสร้างสคริปต์ตัวตัดคำ


1

คุณยังสามารถทำสิ่งนี้: from filename import something

ตัวอย่าง: from client import Client โปรดทราบว่าคุณไม่ต้องการ.py .pyw .pyuiส่วนขยาย


1

นี่คือวิธีที่ฉันเรียกฟังก์ชันจากไฟล์ไพ ธ อนซึ่งมีความยืดหยุ่นสำหรับฉันที่จะเรียกใช้ฟังก์ชันใด ๆ

import os, importlib, sys

def callfunc(myfile, myfunc, *args):
    pathname, filename = os.path.split(myfile)
    sys.path.append(os.path.abspath(pathname))
    modname = os.path.splitext(filename)[0]
    mymod = importlib.import_module(modname)
    result = getattr(mymod, myfunc)(*args)
    return result

result = callfunc("pathto/myfile.py", "myfunc", arg1, arg2)

การสร้างฟังก์ชั่นใหม่ดีกว่าการใช้ฟังก์ชั่นโดยตรงได้อย่างไร?
qwr

@qwr ฟังก์ชั่นใหม่ callfunc () เป็นเพียงเสื้อคลุมของรหัสที่จะเรียกใช้ฟังก์ชั่นเป้าหมายในไฟล์หลามแบบไดนามิก ตัวอย่างที่ให้มาคือเป้าหมาย "myfunc" ในไฟล์ python "pathto / myfile.py" คุณหมายถึงอะไรโดยใช้ฟังก์ชั่นโดยตรง
Xiao-Feng Li

ทำงานอย่างสมบูรณ์แบบสำหรับฉัน ในตัวอย่างของฉันฉันแทนที่: กับfrom mypath import Path Path = callfunc("/folder/to/mypath.py", "Path")ขอบคุณ @ Xiao-FengLi
user319436

@ user319436 ดีใจที่คำตอบของฉันช่วยคนได้ในที่สุด :)
Xiao-Feng Li

ขอบคุณ @ xiao-feng-li !! คำตอบที่ดี !!
Altieres de Matos

0

มีหลายวิธีตามที่ระบุไว้ข้างต้น แต่ฉันพบว่าฉันต้องการนำเข้าเนื้อหาของไฟล์และไม่ต้องการเขียนบรรทัดและบรรทัดและต้องนำเข้าโมดูลอื่น ดังนั้นฉันจึงหาวิธีรับเนื้อหาของไฟล์แม้จะมีจุดไวยากรณ์ ( file.property) ซึ่งต่างจากการผสานไฟล์ที่นำเข้ากับของคุณ
ก่อนอื่นนี่คือไฟล์ของฉันที่ฉันจะนำเข้าdata.py

    testString= "A string literal to import and test with"


หมายเหตุ:คุณสามารถใช้.txtส่วนขยายแทน
ในmainfile.pyเริ่มต้นด้วยการเปิดและรับเนื้อหา

    #!usr/bin/env python3
    Data=open('data.txt','r+').read()

ตอนนี้คุณมีเนื้อหาเป็นสตริง แต่การพยายามเข้าถึงdata.testStringจะทำให้เกิดข้อผิดพลาดเช่นเดียวกับdataอินสแตนซ์ของstrคลาสและแม้ว่ามันจะมีคุณสมบัติtestStringมันจะไม่ทำสิ่งที่คุณคาดหวัง
จากนั้นสร้างคลาส เช่น (ตั้งใจจะเล่นสำนวน),ImportedFile

    class ImportedFile:

และใส่มันลงไป (ด้วยการย่อหน้าที่เหมาะสม):

    exec(data)


และสุดท้ายกำหนดใหม่dataเช่น:

    data=ImportedFile()

และนั่นมัน! การเข้าถึงเช่นเดียวกับที่คุณจะสำหรับการใด ๆ อื่น ๆ โมดูลพิมพ์จะพิมพ์ไปยังคอนโซล print(data.testString) อย่างไรก็ตามหากคุณต้องการให้เทียบเท่าเพียงแค่ปล่อยคลาสการกำหนดอินสแตนซ์และยกเลิกการลบA string literal to import and test with
from mod import *exec

หวังว่านี่จะช่วยได้ :)
-Benji


คุณคิดอย่างจริงจังว่าการอ่านเนื้อหาของไฟล์เป็นสตริงและดำเนินการเป็นวิธีการแก้ปัญหาที่ดีเมื่อเรามีวิธีการแก้ปัญหาอื่น ๆ ทั้งหมดที่คนโพสต์?
qwr

@qwr Erm ใช่ฉันทำ คำตอบอื่น ๆ จำนวนมากไม่ทำงานในบางสถานการณ์ นี่คือเหตุผลที่ฉันต้องการวิธีง่ายๆที่รับรองว่าจะทำงาน หากคุณไม่สามารถมองเห็นสิ่งต่าง ๆ จากมุมมองของคนอื่นได้คุณต้องลองใช้ IDLE อย่างเป็นทางการ
Benj

0

หนึ่งในคุณสมบัติที่ไม่รู้จักของ Python คือความสามารถในการนำเข้าzipไฟล์:

library.zip
|-library
|--__init__.py

ไฟล์__init__.pyของแพ็คเกจประกอบด้วย:

def dummy():
    print 'Testing things out...'

เราสามารถเขียนสคริปต์อื่นซึ่งสามารถนำเข้าแพคเกจจากไฟล์ zip ได้ จำเป็นต้องเพิ่มไฟล์ zip ใน sys.path เท่านั้น

import sys
sys.path.append(r'library.zip')

import library

def run():
    library.dummy()

run()

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