วิธีการรับการอ้างอิงถึงโมดูลภายในโมดูลเอง?


158

ฉันจะรับการอ้างอิงถึงโมดูลจากภายในโมดูลนั้นได้อย่างไร นอกจากนี้ฉันจะรับการอ้างอิงถึงแพ็คเกจที่มีโมดูลนั้นได้อย่างไร


7
ฉันสงสัยว่าคุณอาจถามคำถามนี้เพราะคุณมีตัวแปรอยู่ในขอบเขตโมดูล (เช่น BLAH = 10 ภายนอกฟังก์ชั่นหรือคลาส) จากนั้นตัวแปรคลาส / ฟังก์ชั่นชื่อ BLAH และคุณต้องการแยกความแตกต่าง คำถามที่ถูกต้องที่นี่คือ: จำเป็นหรือไม่ กฎของขอบเขตมีแนวโน้มที่จะเกิดความผิดพลาดโดยเฉพาะอย่างยิ่ง 'คนบ้า' ที่รับรหัสของคุณหลังจากที่คุณ (เช่นคุณ 6 เดือนต่อมา) เทคนิคเช่นนี้ไม่ค่อยจำเป็น ฉันพยายามหลีกเลี่ยงอย่างสมบูรณ์เพราะพวกเขามักจะสับสนและแก้ไขอย่างผิดพลาดในภายหลัง
Kevin J. Rice

2
@ KevinJ.Rice "คนบ้า" ที่รับรหัสของคุณหลังจากที่คุณ (เช่นคุณ 6 เดือนต่อมา) "ทำวันของฉัน!
arctelix

8
ใครสนใจว่าทำไมเขาถึงถามคำถาม มีเหตุผลที่ถูกต้องมากมายที่ต้องทำ
Christopher Barber

จำเป็นต้องปิด มีประโยชน์มากเกินไป
mlvljr

คำตอบ:


211
import sys
current_module = sys.modules[__name__]

3
ยกเว้นสิ่งนี้จะไม่ถูกต้องนักหากมีการโหลดโมดูลใหม่ ฉันไม่คิดว่าจะมีสถานที่ใด ๆ ที่รับประกันการอ้างอิงที่จะเก็บไว้ถ้ามีการโหลดซ้ำจะไม่ทำงานใช่ไหม?
Dima Tisnek

14
การโหลดซ้ำใช้วัตถุโมดูลเดียวกัน ไม่มีการสร้างวัตถุโมดูลใหม่ดังนั้นจึงยังคงถูกต้องเมื่อทำการโหลดซ้ำ
bukzor

18

อีกหนึ่งเทคนิคที่ไม่นำเข้าโมดูล sys และเนื้อหา - ขึ้นอยู่กับรสนิยมของคุณ - ง่ายขึ้น:

current_module = __import__(__name__)

ระวังไม่มีการนำเข้า Python นำเข้าแต่ละโมดูลเพียงครั้งเดียว


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

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

16

หากคุณมีคลาสในโมดูลนั้น__module__คุณสมบัติของคลาสคือชื่อโมดูลของคลาส sys.modules[klass.__module__]ดังนั้นคุณสามารถเข้าถึงโมดูลผ่าน นอกจากนี้ยังใช้งานได้กับฟังก์ชั่น


4
ที่จริงแล้วดูเหมือนว่า (อย่างน้อย) สำหรับฟังก์ชั่น__module__สถานที่ให้บริการไม่ได้เป็นโมดูล แต่สตริง; ดังนั้นความinspect.getabsfile(func.__module__)ล้มเหลวด้วย " TypeError: 'os' ไม่ใช่โมดูลคลาสวิธีการฟังก์ชันการติดตามย้อนกลับเฟรมหรือวัตถุรหัส "; ในขณะที่inspect.getabsfile(sys.modules[o.__module__])ดูเหมือนว่าจะผ่าน
sdaau

12

คุณสามารถรับชื่อของโมดูลปัจจุบันได้โดยใช้ __name__

การอ้างอิงโมดูลสามารถพบได้ใน sys.modulesพจนานุกรม

ดูเอกสาร Python


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