كيفية التحقق من الوحدات الفرعية في بايثون باستخدام hasattr

StackOverflow https://stackoverflow.com/questions/3237355

  •  14-09-2020
  •  | 
  •  

سؤال

في وقت التشغيل، يحصل كود 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')

بهذه السهولة =)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top