كيفية التحقق من الوحدات الفرعية في بايثون باستخدام hasattr
سؤال
في وقت التشغيل، يحصل كود Python على اسم الوحدة الفرعية المراد تحميلها، وهو ما لم أعرفه من قبل.الآن، أريد التحقق من وجود هذه الوحدة الفرعية داخل وحدة موجودة.النظر في هذا الهيكل، حيث foo
و bar
يمكن تحديد:
master/
|
|- __init__.py
|
|- foo/
| |
| |- __init__.py
|
|- bar/
|
|- __init__.py
الآن، عادةً ما أفعل هذا، وهو ما يناسب المحددات والمتغيرات:
import master
unknown_submodule = "foo"
if hasattr(master, unknown_submodule):
pass # all's well
أو أكتشف خطأ AttributeError، الذي يعمل بشكل متساوٍ.
ومع ذلك، مع بنية الملف أعلاه، أنا غير قادر على طرح هذا النهج والعمل به. hasattr()
يُرجع الخطأ دائمًا (أي أنه يوجد دائمًا خطأ في السمة).
إذا نظرت إلى dir(master)
, ، أرى هذا الإخراج:
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
وحتى تحديد صراحة __all__
في master/__init__.py
لا يساعد، ولكن يغير dir() إلى
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']
هل لديك أي فكرة عما أفعله بشكل خاطئ، أو إذا كانت هناك طريقة لتحقيق هذا النوع من الاختبارات؟(بالمناسبة:Python 2.6 على Win/Cygwin، إذا كان ذلك ذا أهمية)
المحلول
الوحدات الفرعية ليست سمات للوحدات الأصلية الخاصة بها ما لم يُنص عليها صراحةً.ما عليك سوى محاولة استيراد الوحدة والتقاطها ImportError
:
try:
__import__("os.peth", fromlist=[os])
except ImportError:
pass
نصائح أخرى
يمكنك ان تفعل
try:
import module.submodule
except ImportError:
print 'failed or whatever'
لقد اضطررت مؤخرًا إلى التحقق من وجود الوحدة الفرعية وبما أنني أستخدم python 3.4.1، فأنا أقدم إجابة جديدة على السؤال:
في بيثون 3.4.1 يمكنك استخدامها importlib.util.find_spec(name, package=None)
(https://docs.python.org/3.4/library/importlib.html#importlib.util.find_spec)
import importlib
module_exists = importlib.util.find_spec('path.to.my.module')
بهذه السهولة =)