كيف يمكنني الوصول الحالية المنفذة وحدة أو اسم الفئة في الثعبان ؟
سؤال
وأود أن تكون قادرة على حيوي استرداد الحالي تنفيذ وحدة أو اسم الفئة من داخل وحدة المستوردة.هنا بعض التعليمات البرمجية:
foo.py:
def f():
print __name__
bar.py:
from foo import f
def b(): f()
ومن الواضح أن هذا لا يعمل كما هو __name__
هو اسم الوحدة النمطية التي تحتوي على وظيفة.ما أود أن يكون الوصول إلى داخل foo
وحدة هو اسم الحالية المنفذة وحدة نمطية باستخدام foo
.حتى في الحالة المذكورة أعلاه سيكون bar
ولكن إذا أي وحدة المستوردة foo
أود foo
حيوي الوصول إلى اسم الوحدة النمطية.
تحرير: على inspect
وحدة تبدو واعدة جدا ولكن ليس بالضبط ما كنت أبحث عنه.ما كان يتمنى نوع من العالمية أو بيئة متغير على مستوى يمكنني الوصول التي تحتوي على اسم الحالية المنفذة وحدة.لا أنا غير راغبة في اجتياز المكدس إلى العثور على تلك المعلومات - ظننت أن الثعبان قد كشفت أن البيانات بالفعل.
تحرير: هنا هو كيف أنا أحاول أن استخدام هذا.لدي اثنين من مختلف جانغو التطبيقات التي على حد سواء بحاجة إلى تسجيل الأخطاء إلى ملف.يتيح القول أن ما يطلق عليه "AppOne" و "AppTwo".أود أيضا أن يكون المكان الذي أود أن تسجيل هذه الملفات:"/home/hare/app_logs
".في كل تطبيق في أي نقطة أود أن تكون قادرة على استيراد مسجل وحدة استدعاء وظيفة السجل الذي يكتب السجل السلسلة إلى الملف.لكن ما أود القيام به هو إنشاء دليل تحت app_logs
هذا هو اسم التطبيق الحالي ("AppOne" أو "AppTwo") بحيث كل تطبيق ملفات السجل سوف تذهب في كل منهما تسجيل الدلائل.
من أجل القيام بذلك وأعتقد أن أفضل طريقة أن يكون مسجل وحدة الوصول إلى نوع من العالمية المتغيرة التي تدل الحالي اسم التطبيق كما هو مسؤول عن معرفة مكان الأصل دليل التسجيل و إنشاء التطبيق تسجيل الدليل إذا كان لا يوجد بعد.
المحلول
من التعليق ليس السؤال.
أنا ببساطة من الغريب أن نرى إذا ما أحاول فعله هو ممكن.
جواب "هل من الممكن" دائما "نعم".دائما.إلا إن سؤالك ينطوي على السفر عبر الزمن الجاذبية المضادة أو الحركة الدائبة.
منذ الجواب دائما "نعم", السؤال هو سوء تشكيلها.السؤال الحقيقي هو: "ما هو وسيلة جيدة إلى وحدة تسجيل تعرف اسم العميل ؟" أو شيء من هذا القبيل.
الجواب هو "قبول ذلك كمعلمة." لا تعبث مع تفتيش أو تبحث عن الغامض globals أو غيرها من الحيل.
فقط اتبع تصميم نمط من قطع الأشجار.getLogger() واستخدام صراحة اسمه قطع الاشجار.لغة مشتركة هي التالية
logger= logging.getLogger( __name__ )
الذي يعالج تقريبا جميع سجل التسمية تماما.
نصائح أخرى
هذا يجب أن تعمل من أجل الرجوع إلى الوحدة الحالية:
import sys
sys.modules[__name__]
إن "حاليا تنفيذ وحدة" من الواضح فو ، كما أن ما يحتوي على وظيفة يعمل حاليا - أعتقد أن أفضل وصف ما تريده هو وحدة من فو المباشر المتصل (الذي قد يكون في حد ذاته فو إذا كنت تدعو و() من وظيفة في فو دعا من خلال وظيفة في البار.إلى أي مدى تريد أن تذهب حتى يعتمد على ما تريد هذا.
في أي حال ، على افتراض انك تريد الفوري المتصل, يمكنك الحصول على هذا من خلال السير مكدس الاستدعاءات.يمكن تحقيق هذا عن طريق الدعوة sys._getframe
, مع aprropriate عدد من المستويات الأقدام.
def f():
caller = sys._getframe(1) # Obtain calling frame
print "Called from module", caller.f_globals['__name__']
[عدل]:في الواقع, استخدام فحص وحدة على النحو المقترح أعلاه هو على الارجح نظافة طريقة الحصول على الإطار المكدس.أي ما يعادل رمز:
def f():
caller = inspect.currentframe().f_back
print "Called from module", caller.f_globals['__name__']
(sys._getframe موثقة بأنها للاستخدام الداخلي - فحص الوحدة هي أكثر موثوقية API)
أعتقد أن ما كنت ترغب في استخدام فحص وحدة فحص python runtime المكدس.تحقق من هذا البرنامج التعليمي.أعتقد أنه يوفر تقريبا بالضبط ما تريد القيام به.
__file__
هو مسار الوحدة الحالية يتم إجراء المكالمة.
للحصول على إشارة إلى "__main__" الوحدة عندما تكون في آخر:
import sys
sys.modules['__main__']
ثم الحصول على وحدة مسار الملف الذي يتضمن اسمها:
sys.modules['__main__'].__file__
إذا ضمن "__main__" وحدة ببساطة الاستخدام: __file__
للحصول على مجرد اسم الملف من مسار الملف:
import os
os.path.basename(file_path)
فصل اسم الملف من امتداده:
file_name.split(".")[0]
للحصول على اسم فئة سبيل المثال:
instance.__class__.__name__
للحصول على اسم الدرجة:
class.__name__
أنا لا أعتقد أن هذا ممكنا منذ أن خرجت من foo
's نطاق.فو سوف فقط يكون على بينة من الداخلية نطاق لأنه قد يكون استدعائه من قبل عدد لا يحصى من وحدات أخرى والتطبيقات.
باستخدام __file__
وحده يعطيك مسار نسبي الرئيسية وحدة مسار مطلق المستوردة وحدات.يجري على بينة من هذا يمكننا الحصول على وحدة الملف باستمرار إما مع القليل من المساعدة من os.path
أدوات.
على اسم الملف فقط استخدام __file__.split(os.path.sep)[-1]
.
من أجل استكمال مسار استخدام os.path.abspath(__file__)
.
Demo:
/tmp $ cat f.py
from pprint import pprint
import os
import sys
pprint({
'sys.modules[__name__]': sys.modules[__name__],
'__file__': __file__,
'__file__.split(os.path.sep)[-1]': __file__.split(os.path.sep)[-1],
'os.path.abspath(__file__)': os.path.abspath(__file__),
})
/tmp $ cat i.py
import f
النتائج:
## on *Nix ##
/tmp $ python3 f.py
{'sys.modules[__name__]': <module '__main__' from 'f.py'>,
'__file__': 'f.py',
'__file__.split(os.path.sep)[-1]': 'f.py',
'os.path.abspath(__file__)': '/tmp/f.py'}
/tmp $ python3 i.py
{'sys.modules[__name__]': <module 'f' from '/tmp/f.pyc'>,
'__file__': '/tmp/f.pyc',
'__file__.split(os.path.sep)[-1]': 'f.pyc',
'os.path.abspath(__file__)': '/tmp/f.pyc'}
## on Windows ##
PS C:\tmp> python3.exe f.py
{'sys.modules[__name__]': <module '__main__' from 'f.py'>,
'__file__': 'f.py',
'__file__.split(os.path.sep)[-1]': 'f.py',
'os.path.abspath(__file__)': 'C:\\tools\\cygwin\\tmp\\f.py'}
PS C:\tmp> python3.exe i.py
{'sys.modules[__name__]': <module 'f' from 'C:\\tools\\cygwin\\tmp\\f.py'>,
'__file__': 'C:\\tools\\cygwin\\tmp\\f.py',
'__file__.split(os.path.sep)[-1]': 'f.py',
'os.path.abspath(__file__)': 'C:\\tools\\cygwin\\tmp\\f.py'}
إذا كنت ترغب في غزة '.py من النهاية ، يمكنك أن تفعل ذلك بسهولة.(ولكن لا ننسى أن كنت قد تشغيل '.بيك' بدلا من ذلك.)
انها كانت فترة من الوقت منذ أن كنت قد فعلت الثعبان, ولكن أعتقد أنه يمكنك الحصول على الوصول إلى globals و السكان المحليين من المتصل من خلال traceback.
إذا كنت تريد فقط اسم الملف:
file_name = __file__.split("/")[len(__file__.split("/"))-1]
للحصول على الملف الحالي الوحدة النمطية التي تحتوي على المجلد هنا هو ما عملت بالنسبة لي:
import os
parts = os.path.splitext(__name__)
module_name = parts[len(parts) - 2]