ฉันกำลังเขียนแอปพลิเคชัน Python ที่ใช้เป็นคำสั่งเป็นอาร์กิวเมนต์ตัวอย่างเช่น:
$ python myapp.py command1
ฉันต้องการให้แอปพลิเคชันสามารถขยายได้นั่นคือเพื่อให้สามารถเพิ่มโมดูลใหม่ที่ใช้คำสั่งใหม่โดยไม่ต้องเปลี่ยนแหล่งแอพพลิเคชันหลัก ต้นไม้ดูเหมือนว่า:
myapp/
__init__.py
commands/
__init__.py
command1.py
command2.py
foo.py
bar.py
ดังนั้นฉันต้องการให้แอปพลิเคชันค้นหาโมดูลคำสั่งที่มีอยู่ตอนรันไทม์และดำเนินการโมดูลที่เหมาะสม
Python กำหนดฟังก์ชั่น__import__ซึ่งรับสตริงสำหรับชื่อโมดูล:
__import __ (ชื่อ, globals = None, locals = None, fromlist = (), level = 0)
ฟังก์ชันนำเข้าชื่อโมดูลซึ่งอาจใช้ globals และ locals ที่กำหนดเพื่อกำหนดวิธีตีความชื่อในบริบทแพ็คเกจ รายการจากให้ชื่อของวัตถุหรือ submodules ที่ควรจะนำเข้าจากโมดูลที่กำหนดโดยชื่อ
ที่มา: https://docs.python.org/3/library/functions.html# นำเข้า
ดังนั้นในปัจจุบันฉันมีสิ่งที่ชอบ:
command = sys.argv[1]
try:
command_module = __import__("myapp.commands.%s" % command, fromlist=["myapp.commands"])
except ImportError:
# Display error message
command_module.run()
มันใช้งานได้ดีฉันแค่สงสัยว่าอาจมีวิธีที่เป็นไปได้มากกว่าในการทำสิ่งที่เราทำกับรหัสนี้
โปรดทราบว่าฉันไม่ต้องการเข้าใช้ไข่หรือจุดส่วนขยายโดยเฉพาะ นี่ไม่ใช่โครงการโอเพ่นซอร์สและฉันไม่คาดหวังว่าจะมี "ปลั๊กอิน" จุดประสงค์เพื่อลดความซับซ้อนของรหัสแอปพลิเคชันหลักและลบความจำเป็นในการแก้ไขในแต่ละครั้งที่มีการเพิ่มโมดูลคำสั่งใหม่
dir(__import__)
ในเปลือกหลามพิมพ์นี้: รายการจากควรเป็นรายชื่อที่จะเลียนแบบ "จากการนำเข้าชื่อ ... "
importlib
: stackoverflow.com/a/54956419/687896