كيف يمكنني الوصول الحالية المنفذة وحدة أو اسم الفئة في الثعبان ؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

وأود أن تكون قادرة على حيوي استرداد الحالي تنفيذ وحدة أو اسم الفئة من داخل وحدة المستوردة.هنا بعض التعليمات البرمجية:

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]
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top