วิธีการดึงเส้นทางของโมดูล


755

ฉันต้องการตรวจสอบว่ามีการเปลี่ยนแปลงโมดูล ตอนนี้การใช้ inotify นั้นง่ายคุณแค่ต้องรู้ไดเรกทอรีที่คุณต้องการรับการแจ้งเตือน

ฉันจะดึงเส้นทางของโมดูลในไพ ธ อนได้อย่างไร


1
ลองดู modulefinder: docs.python.org/library/modulefinder.html

9
หากคุณยังคงมองในเว็บไซต์นี้โปรดอัปเดตเป็นคำตอบที่ถูกต้องในการนี้ มันสะอาดกว่าโซลูชันที่เสนอและใช้งานได้ในกรณีที่__file__ไม่ได้ตั้งค่าไว้
erikbwork

3
@ erikb85: มันไม่เพียงทำความสะอาด inspectโซลูชันพื้นฐานยังใช้กับexecfile()กรณีเมื่อ__file__สร้างชื่อผิดอย่างเงียบ ๆ
jfs


import pathlib, module; pathlib.Path(module.__file__).resolve().parentนี่เป็นแพลตฟอร์ม
อิสระ

คำตอบ:


906
import a_module
print(a_module.__file__)

จริงจะให้เส้นทางไปยังไฟล์. pyc ที่โหลดอย่างน้อยใน Mac OS X ดังนั้นฉันเดาว่าคุณสามารถทำได้:

import os
path = os.path.abspath(a_module.__file__)

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

path = os.path.dirname(a_module.__file__)

เพื่อรับไดเรกทอรีของโมดูล


54
สิ่งนี้จะตอบวิธีรับพา ธ ของโมดูลที่คุณนำเข้า แต่ไม่ใช่ของโมดูล / สคริปต์ที่คุณอยู่ (สำหรับสคริปต์ที่คุณใช้__file__ไม่ได้เป็นพา ธ เต็มมันสัมพันธ์กัน) สำหรับไฟล์ที่ฉันอยู่ฉันต้องนำเข้าโมดูลอื่นจากไดเรกทอรีเดียวกันและทำตามที่แสดงไว้ที่นี่ ไม่มีใครรู้วิธีที่สะดวกกว่านี้ไหม?
Ben Bryant

5
@hbdgaf ค่อนข้างแน่ใจว่าไม่มีสิ่งนั้นเป็นแบบในตัวself.__file__
Dan Passaro

26
@BenBryant @hbdgaf os.path.dirname(__file__)ทำงานได้ดีสำหรับฉันและส่งคืนเส้นทาง abs ของไดเรกทอรีของโมดูล
Niccolò

9
ฉันพยายามทำสิ่งนี้และรับการติดตามกลับ: AttributeError: 'module' object has no attribute '__file__'
Dorian Dore

5
@DorianDore ฉันยุ่งกับโมดูลเพียงเล็กน้อยและได้รับการแก้ปัญหาpath = module.__path__.__dict__["_path"][0]แต่ฉันไม่แน่ใจว่ามันเป็นแบบพกพาหรือหากไม่แตกต่างกันระหว่างรุ่นหลาม มันทำงานสำหรับฉันแตกต่างจากคำตอบนี้ซึ่งจะช่วยให้ฉันและข้อผิดพลาดเดียวกันinspectคำตอบยกTypeError: <module 'module' (namespace)> is a built-in module...
Jezor

279

มีinspectโมดูลในหลาม

เอกสารอย่างเป็นทางการ

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

ตัวอย่าง:

>>> import os
>>> import inspect
>>> inspect.getfile(os)
'/usr/lib64/python2.7/os.pyc'
>>> inspect.getfile(inspect)
'/usr/lib64/python2.7/inspect.pyc'
>>> os.path.dirname(inspect.getfile(inspect))
'/usr/lib64/python2.7'

7
คุณสามารถใช้inspectเพื่อรับชื่อของไฟล์ปัจจุบันได้เช่นกัน ดูstackoverflow.com/a/50905/320036
z0r

5
ฉัน googled คำถามนี้หลายครั้งและนี่คือคำตอบที่สมเหตุสมผลที่สุดที่ฉันเคยเห็น! โปรดอัปเดตข้อมูลเกี่ยวกับinspect.currentframe()
erikbwork

inspect.getfile()วิธีการไม่ได้ทำงานกับโมดูลแต่ทำงานร่วมกับโมดูล_io io
smwikipedia

70

ดังที่คำตอบอื่น ๆ ได้กล่าวไว้วิธีที่ดีที่สุดในการทำเช่นนี้คือ__file__(แสดงให้เห็นอีกครั้งด้านล่าง) อย่างไรก็ตามมีข้อแม้ที่สำคัญซึ่ง__file__ไม่มีอยู่หากคุณกำลังเรียกใช้โมดูลด้วยตัวเอง (เช่น__main__)

ตัวอย่างเช่นสมมติว่าคุณมีสองไฟล์ (ทั้งสองไฟล์อยู่ใน PYTHONPATH ของคุณ):

#/path1/foo.py
import bar
print(bar.__file__)

และ

#/path2/bar.py
import os
print(os.getcwd())
print(__file__)

การใช้ foo.py จะให้ผลลัพธ์:

/path1        # "import bar" causes the line "print(os.getcwd())" to run
/path2/bar.py # then "print(__file__)" runs
/path2/bar.py # then the import statement finishes and "print(bar.__file__)" runs

อย่างไรก็ตามถ้าคุณพยายามเรียกใช้ bar.py ด้วยตัวเองคุณจะได้รับ:

/path2                              # "print(os.getcwd())" still works fine
Traceback (most recent call last):  # but __file__ doesn't exist if bar.py is running as main
  File "/path2/bar.py", line 3, in <module>
    print(__file__)
NameError: name '__file__' is not defined 

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


5
ในกรณีนี้คุณสามารถใช้ sys.argv [0] ในสถานที่ของไฟล์
Jimothy

4
นั่นเป็นข้อแม้เฉพาะรุ่นหรือไม่ ใน 2.6 และ 2.7 ฉันใช้ไฟล์ได้สำเร็จซึ่งทำงานกับไฟล์เมื่อชื่อ __ == '__ main ' กรณีความล้มเหลวเพียงอย่างเดียวที่ฉันเห็นคือ "python -c 'print file '" ฉันจะเพิ่มว่าบางครั้งไฟล์อาจเป็น '<stdin>' ​​ซึ่งเกิดขึ้นเมื่อ IDEs เช่น emacs เรียกใช้บัฟเฟอร์ปัจจุบัน
Paul Du Bois

1
โปรดทราบว่าตัวอักษร "__" ที่นำหน้าและต่อท้ายใส่ตัวหนาดังนั้นโปรดระลึกไว้เสมอเมื่ออ่านความคิดเห็นก่อนหน้านี้ :-P
Paul Du Bois

1
@PaulDuBois คุณสามารถล้อมรอบด้วยสำบัดสำนวนกลับ: ` __file__` กลายเป็น__file__
fncomp

1
คุณจะได้รับNameErrorอย่างไร @ Paul ดูบัวส์: ฉันได้พยายามหลาม 2.3-3.4 และ__file__มีการกำหนด แต่ฉันเรียกใช้แฟ้มหลาม: python a.py, ,python -ma ./a.py
jfs

43

ฉันจะลองแก้ไขรูปแบบต่าง ๆ ของคำถามนี้ด้วย:

  1. ค้นหาเส้นทางของสคริปต์ที่เรียกว่า
  2. การค้นหาเส้นทางของสคริปต์ที่กำลังดำเนินการอยู่
  3. ค้นหาไดเรกทอรีของสคริปต์ที่เรียกว่า

(คำถามเหล่านี้บางคำถามถูกถามใน SO แต่ถูกปิดเพราะซ้ำซ้อนและเปลี่ยนเส้นทางที่นี่)

การใช้งาน __file__

สำหรับโมดูลที่คุณนำเข้า:

import something
something.__file__ 

จะคืนค่าพา ธสัมบูรณ์ของโมดูล อย่างไรก็ตามให้สคริปต์ foo.py:

#foo.py
print '__file__', __file__

โทรหาด้วย 'python foo.py' จะกลับมาง่ายๆ 'foo.py' หากคุณเพิ่ม shebang:

#!/usr/bin/python 
#foo.py
print '__file__', __file__

และเรียกมันโดยใช้. /foo.py มันจะกลับมา './foo.py' เรียกจากไดเรกทอรีอื่น (เช่นวาง foo.py ในแถบไดเรกทอรี) จากนั้นเรียกทั้งคู่

python bar/foo.py

หรือเพิ่ม Shebang และเรียกใช้ไฟล์โดยตรง:

bar/foo.py

จะส่งคืน 'bar / foo.py' ( เส้นทางสัมพัทธ์ )

ค้นหาไดเรกทอรี

ตอนนี้ไปจากที่นั่นเพื่อรับไดเรกทอรีos.path.dirname(__file__)ยังสามารถหากิน อย่างน้อยในระบบของฉันมันจะคืนค่าสตริงว่างถ้าคุณเรียกมันจากไดเรกทอรีเดียวกับไฟล์ อดีต

# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)

จะส่งออก:

__file__ is: foo.py
os.path.dirname(__file__) is: 

กล่าวอีกนัยหนึ่งมันจะส่งคืนสตริงว่างดังนั้นจึงไม่น่าเชื่อถือหากคุณต้องการใช้สำหรับไฟล์ปัจจุบัน(ตรงข้ามกับไฟล์ของโมดูลที่นำเข้า) ในการหลีกเลี่ยงปัญหานี้คุณสามารถปิดมันด้วยการโทรหาผู้ที่ไม่เห็นด้วย:

# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))

ซึ่งแสดงผลเช่น:

os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar

โปรดทราบว่า abspath () ไม่สามารถแก้ไขลิงก์ได้ หากคุณต้องการทำสิ่งนี้ให้ใช้ realpath () แทน ตัวอย่างเช่นการสร้าง symlink file_import_testing_link ให้ชี้ไปที่ file_import_testing.py โดยมีเนื้อหาดังต่อไปนี้:

import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)

การดำเนินการจะพิมพ์เส้นทางที่แน่นอนเช่น:

abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py

file_import_testing_link -> file_import_testing.py

ใช้ตรวจสอบ

@SummerBreeze กล่าวถึงโดยใช้โมดูลตรวจสอบ

ดูเหมือนว่าจะทำงานได้ดีและค่อนข้างสั้นสำหรับโมดูลที่นำเข้า:

import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)

เชื่อฟังส่งคืนพา ธ สัมบูรณ์ อย่างไรก็ตามสำหรับการค้นหาเส้นทางของสคริปต์ที่กำลังดำเนินการอยู่ฉันไม่เห็นวิธีใช้งาน


1
inspect.getfile (os) เหมือนกับ os .__ file__ จากรหัส: def getfile (object): "" "หาแหล่งที่มาหรือไฟล์ที่คอมไพล์วัตถุที่กำหนดไว้ใน" "" ถ้า ismodule (ถ้ามี) (object, ' file '): return object .__ file__
idanzalz

4
คุณสามารถใช้inspect.getfile(inspect.currentframe())เพื่อรับเส้นทางของสคริปต์ที่กำลังทำงานอยู่
jbochi

33

ฉันไม่เข้าใจว่าทำไมไม่มีใครพูดถึงเรื่องนี้ แต่สำหรับฉันทางออกที่ง่ายที่สุดคือการใช้imp.find_module ("modulename") (เอกสารที่นี่ ):

import imp
imp.find_module("os")

มันให้สิ่งอันดับกับเส้นทางในตำแหน่งที่สอง:

(<open file '/usr/lib/python2.7/os.py', mode 'U' at 0x7f44528d7540>,
'/usr/lib/python2.7/os.py',
('.py', 'U', 1))

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

แก้ไข :

ใน python3 importlibโมดูลควรทำ:

เอกสารของimportlib.util.find_spec:

ส่งคืนข้อมูลจำเพาะสำหรับโมดูลที่ระบุ

ก่อนอื่น sys.modules จะถูกตรวจสอบเพื่อดูว่าโมดูลถูกอิมพอร์ตแล้ว ถ้าเป็นเช่นนั้น sys.modules [ชื่อ] ส่งคืนข้อมูลจำเพาะ หากสิ่งนั้นเกิดขึ้นที่จะถูกตั้งค่าเป็นไม่มีดังนั้น ValueError จะเพิ่มขึ้น หากโมดูลไม่ได้อยู่ใน sys.modules ดังนั้น sys.meta_path จะค้นหาสเป็คที่เหมาะสมพร้อมค่า 'เส้นทาง' ที่มอบให้แก่ผู้ค้นหา ไม่มีการส่งคืนหากไม่พบสเป็ค

หากชื่อสำหรับ submodule (มีจุด) โมดูลหลักจะถูกนำเข้าโดยอัตโนมัติ

อาร์กิวเมนต์ชื่อและแพ็กเกจทำงานเหมือนกับ importlib.import_module () กล่าวอีกนัยหนึ่งชื่อโมดูลสัมพันธ์ (ที่มีจุดนำ) ทำงาน


2
imp ไม่ได้ถูกคิดค่าเสื่อมราคาใน python 2 (เวอร์ชันปัจจุบัน 2.7.13) imp ถูกคิดค่าเสื่อมราคาใน python 3 ตั้งแต่ 3.4 importlib จะใช้ใน python 3 แทน ฉันชอบโซลูชันนี้เพราะใช้งานได้แม้ในขณะที่การนำเข้าจริงจะล้มเหลว (เช่นเนื่องจากโมดูล 64 บิตสำหรับ
เอ็นจิ้น

และเป็นเรื่องที่ดีมากเมื่อพยายามค้นหาเส้นทาง 64 บิต sqlite3 และการนำเข้าล้มเหลว สมบูรณ์
rahvin_t

2
importlib.machinery.PathFinder().find_module("os").get_filename()ทางเลือกที่สั้นที่สุดที่imp.find_moduleฉันพบใน Python3 + importlib.util.find_specหากใครที่กำลังมองหาการใช้งานของ
Torxed

วิธีนี้ใช้งานได้โดยไม่ต้องนำเข้าโมดูลจริงซึ่งยอดเยี่ยมมากเพราะฉันใช้วิธีนี้เพื่อหาว่าโมดูลรุ่นใดกำลังนำเข้าจากคอมพิวเตอร์ที่ใช้ร่วมกัน
Gouda

19

นี่เป็นเรื่องเล็กน้อย

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

ดังนั้นการรับไดเรกทอรีสำหรับโมดูลเพื่อแจ้งให้ทราบนั้นเป็นเรื่องง่ายเหมือน:

os.path.dirname(__file__)

14
เกือบ แต่ไม่ถูกต้อง - ไฟล์เป็นไม่ได้ "เมื่อเทียบกับที่คุณอยู่ที่ตอนนี้"; เมื่อมันเป็นญาติ (ซึ่งมันจะเป็นเฉพาะเมื่อมีเส้นทางญาติใน sys.path) ก็เทียบกับที่คุณได้เมื่อโมดูลถูกโหลด
Charles Duffy

17
import os
path = os.path.abspath(__file__)
dir_path = os.path.dirname(path)

1
ไม่ทำงานบน Linux python 2.6 ของฉันเนื่องจาก__file__เป็นเพียง dir / test.py, abspath เกี่ยวข้องกับ cwd เพื่อทำให้ชื่อพา ธ ซึ่งไม่ได้ผลลัพธ์ที่ต้องการ แต่ถ้าคุณนำเข้าโมดูลก็m.__file__จะให้ผลลัพธ์ที่ต้องการ
Ben Bryant

10
import module
print module.__path__

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

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

แหล่ง


9

ยูทิลิตี้บรรทัดคำสั่ง

คุณสามารถปรับแต่งมันเป็นโปรแกรมอรรถประโยชน์บรรทัดคำสั่ง

python-which <package name>

ป้อนคำอธิบายรูปภาพที่นี่


สร้าง /usr/local/bin/python-which

#!/usr/bin/env python

import importlib
import os
import sys

args = sys.argv[1:]
if len(args) > 0:
    module = importlib.import_module(args[0])
    print os.path.dirname(module.__file__)

ทำให้ปฏิบัติการได้

sudo chmod +x /usr/local/bin/python-which

7

ดังนั้นฉันจึงใช้เวลาพอสมควรในการพยายามทำเช่นนี้กับ py2exe ปัญหาก็คือการได้รับโฟลเดอร์ฐานของสคริปต์ไม่ว่าจะถูกเรียกใช้เป็นสคริปต์ไพ ธ อนหรือปฏิบัติการแบบ py2exe นอกจากนี้เพื่อให้มันทำงานไม่ว่าจะถูกเรียกใช้จากโฟลเดอร์ปัจจุบันโฟลเดอร์อื่นหรือ (นี่คือยากที่สุด) จากเส้นทางของระบบ

ในที่สุดฉันก็ใช้วิธีนี้โดยใช้ sys.frozen เป็นตัวบ่งชี้การทำงานใน py2exe:

import os,sys
if hasattr(sys,'frozen'): # only when running in py2exe this exists
    base = sys.prefix
else: # otherwise this is a regular python script
    base = os.path.dirname(os.path.realpath(__file__))

7

คุณสามารถนำเข้าโมดูลของคุณจากนั้นกดชื่อและคุณจะได้รับเส้นทางแบบเต็ม

>>> import os
>>> os
<module 'os' from 'C:\\Users\\Hassan Ashraf\\AppData\\Local\\Programs\\Python\\Python36-32\\lib\\os.py'>
>>>

4

หากคุณต้องการเรียกรูทพา ธ ของแพ็คเกจออกจากโมดูลใด ๆ ผลงานต่อไปนี้ (ทดสอบบน Python 3.6):

from . import __path__ as ROOT_PATH
print(ROOT_PATH)

__init__.pyเส้นทางหลักยังสามารถอ้างอิงได้โดยใช้__file__แทน

หวังว่านี่จะช่วยได้!


3

หากข้อแม้ของการใช้งานเพียงอย่างเดียว__file__คือเมื่อปัจจุบันไดเรกทอรีสัมพัทธ์จะว่างเปล่า (เช่นเมื่อเรียกใช้เป็นสคริปต์จากไดเรกทอรีเดียวกันกับที่สคริปต์อยู่) ดังนั้นทางออกที่ไม่สำคัญคือ:

import os.path
mydir = os.path.dirname(__file__) or '.'
full  = os.path.abspath(mydir)
print __file__, mydir, full

และผลลัพธ์:

$ python teste.py 
teste.py . /home/user/work/teste

เคล็ดลับคือor '.'หลังจากdirname()โทร มันตั้งค่า dir เป็น.ซึ่งหมายถึงไดเรกทอรีปัจจุบันและเป็นไดเรกทอรีที่ถูกต้องสำหรับฟังก์ชั่นที่เกี่ยวข้องกับเส้นทางใด ๆ

ดังนั้นการใช้งานabspath()จึงไม่จำเป็นอย่างแท้จริง แต่ถ้าคุณใช้อยู่ดีก็ไม่จำเป็นต้องใช้เคล็ดลับ: abspath()ยอมรับเส้นทางที่ว่างเปล่าและแปลความหมายมันเป็นไดเรกทอรีปัจจุบันอย่างถูกต้อง


สลับลำดับที่ดีขึ้นและใช้เพียงos.path.dirname(os.path.abspath(__file__))เพราะคุณไม่ต้องกังวลเกี่ยวกับเส้นทางญาติเลย โอกาสที่น้อยกว่าสำหรับข้อบกพร่อง
szali

3

ฉันต้องการมีส่วนร่วมกับสถานการณ์ทั่วไปหนึ่งเรื่อง (ใน Python 3) และสำรวจวิธีการบางอย่าง

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

เพียงกล่าวว่าหากคุณเรียกใช้ไฟล์สคริปต์ด้วยรหัสต่อไปนี้จะไม่รับประกันว่าexample.txtไฟล์จะถูกสร้างขึ้นในไดเรกทอรีเดียวกันกับที่ตั้งไฟล์สคริปต์:

with open('example.txt', 'w'):
    pass

ในการแก้ไขรหัสนี้เราจำเป็นต้องรับพา ธ ไปยังสคริปต์และทำให้สมบูรณ์ เพื่อให้แน่ใจว่าเส้นทางเป็นแบบสัมบูรณ์เราเพียงใช้ฟังก์ชันos.path.realpath () ในการรับพา ธ ไปยังสคริปต์มีฟังก์ชั่นทั่วไปหลายอย่างที่ส่งคืนผลลัพธ์พา ธ ต่างๆ:

  • os.getcwd()
  • os.path.realpath('example.txt')
  • sys.argv[0]
  • __file__

ฟังก์ชั่นทั้งสองos.getcwd ()และos.path.realpath ()ผลเส้นทางการกลับมาอยู่บนพื้นฐานของไดเรกทอรีการทำงานปัจจุบัน โดยทั่วไปไม่ใช่สิ่งที่เราต้องการ องค์ประกอบแรกของรายการsys.argvคือพา ธ ของสคริปต์รูท (สคริปต์ที่คุณรัน) โดยไม่คำนึงถึงว่าคุณเรียกรายการในสคริปต์รูทเองหรือในโมดูลใด ๆ มันอาจมีประโยชน์ในบางสถานการณ์ __FILE__ตัวแปรประกอบด้วยเส้นทางของโมดูลจากที่ที่มันได้รับการเรียก


รหัสต่อไปนี้สร้างไฟล์example.txtในไดเรกทอรีเดียวกันกับที่สคริปต์ตั้งอยู่อย่างถูกต้อง:

filedir = os.path.dirname(os.path.realpath(__file__))
filepath = os.path.join(filedir, 'example.txt')

with open(filepath, 'w'):
    pass

3

หากคุณต้องการทราบเส้นทางที่แน่นอนจากสคริปต์ของคุณคุณสามารถใช้วัตถุเส้นทาง :

from pathlib import Path

print(Path().absolute())
print(Path().resolve('.'))
print(Path().cwd())

วิธี cwd ()

ส่งคืนวัตถุพา ธ ใหม่ที่แสดงถึงไดเรกทอรีปัจจุบัน (ส่งคืนโดย os.getcwd ())

วิธีการแก้ไข ()

ทำให้เส้นทางเป็นสัมบูรณ์แก้ไข symlink ใด ๆ วัตถุเส้นทางใหม่จะถูกส่งกลับ:


1

จากโมดูลของแพคเกจหลามฉันต้องอ้างถึงไฟล์ที่อยู่ในไดเรกทอรีเดียวกันกับแพคเกจ อดีต

some_dir/
  maincli.py
  top_package/
    __init__.py
    level_one_a/
      __init__.py
      my_lib_a.py
      level_two/
        __init__.py
        hello_world.py
    level_one_b/
      __init__.py
      my_lib_b.py

ดังนั้นข้างต้นฉันต้องโทร maincli.py จากโมดูล my_lib_a.py รู้ว่า top_package และ maincli.py อยู่ในไดเรกทอรีเดียวกัน นี่คือวิธีที่ฉันได้รับเส้นทางไปยัง maincli.py:

import sys
import os
import imp


class ConfigurationException(Exception):
    pass


# inside of my_lib_a.py
def get_maincli_path():
    maincli_path = os.path.abspath(imp.find_module('maincli')[1])
    # top_package = __package__.split('.')[0]
    # mod = sys.modules.get(top_package)
    # modfile = mod.__file__
    # pkg_in_dir = os.path.dirname(os.path.dirname(os.path.abspath(modfile)))
    # maincli_path = os.path.join(pkg_in_dir, 'maincli.py')

    if not os.path.exists(maincli_path):
        err_msg = 'This script expects that "maincli.py" be installed to the '\
        'same directory: "{0}"'.format(maincli_path)
        raise ConfigurationException(err_msg)

    return maincli_path

อ้างอิงจากการโพสต์โดย PlasmaBinturong ฉันแก้ไขรหัส


1

หากคุณต้องการทำสิ่งนี้แบบไดนามิกใน "โปรแกรม" ลองใช้รหัสนี้:
จุดของฉันคือคุณอาจไม่ทราบชื่อที่แน่นอนของโมดูลเพื่อ "hardcode" มันอาจจะถูกเลือกจากรายการหรืออาจไม่ได้ทำงานอยู่เพื่อใช้ __file__

(ฉันรู้ว่ามันจะไม่ทำงานใน Python 3)

global modpath
modname = 'os' #This can be any module name on the fly
#Create a file called "modname.py"
f=open("modname.py","w")
f.write("import "+modname+"\n")
f.write("modpath = "+modname+"\n")
f.close()
#Call the file with execfile()
execfile('modname.py')
print modpath
<module 'os' from 'C:\Python27\lib\os.pyc'>

ฉันพยายามกำจัดปัญหา "global" แต่พบกรณีที่มันไม่ทำงานฉันคิดว่า "execfile ()" สามารถ emulate ใน Python 3 เนื่องจากนี่คือในโปรแกรมมันสามารถใส่ในเมธอดหรือโมดูลสำหรับ นำมาใช้ใหม่


0

หากคุณติดตั้งโดยใช้ pip "pip แสดง" ใช้งานได้ดี ('ตำแหน่ง')

$ pip แสดง detectron2

Name: detectron2
Version: 0.1
Summary: Detectron2 is FAIR next-generation research platform for object detection and segmentation.
Home-page: https://github.com/facebookresearch/detectron2
Author: FAIR
Author-email: None
License: UNKNOWN
Location: /home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages
Requires: yacs, tabulate, tqdm, pydot, tensorboard, Pillow, termcolor, future, cloudpickle, matplotlib, fvcore

0

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

#!/bin/bash
module=${1:?"I need a module name"}

python << EOI
import $module
import os
print os.path.dirname($module.__file__)
EOI

ตัวอย่างเชลล์:

[root@sri-4625-0004 ~]# export LXML=$(get_python_path.sh lxml)
[root@sri-4625-0004 ~]# echo $LXML
/usr/lib64/python2.7/site-packages/lxml
[root@sri-4625-0004 ~]#
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.