पायथन में वर्तमान मॉड्यूल की विशेषताओं का संदर्भ कैसे प्राप्त करें


119

जो मैं करने की कोशिश कर रहा हूं वह कमांड लाइन में इस तरह दिखाई देगा:

>>> import mymodule
>>> names = dir(mymodule)

मैं अपने mymoduleभीतर से परिभाषित सभी नामों का संदर्भ कैसे प्राप्त कर सकता हूं mymodule?

कुछ इस तरह:

# mymodule.py
names = dir(__thismodule__)

जवाबों:


135

बस ग्लोबल्स () का उपयोग करें

ग्लोबल्स () - वर्तमान वैश्विक प्रतीक तालिका का प्रतिनिधित्व करने वाला शब्दकोश लौटाएं। यह हमेशा वर्तमान मॉड्यूल का शब्दकोश है (किसी फ़ंक्शन या विधि के अंदर, यह वह मॉड्यूल है जहां इसे परिभाषित किया जाता है, न कि उस मॉड्यूल से जिसे इसे कहा जाता है)।

http://docs.python.org/library/functions.html#globals


4
क्या परिभाषित मॉड्यूल के बजाय कॉलिंग मॉड्यूल के ग्लोबल्स () तक पहुंचने का कोई तरीका है?
dimo414

9
आप ट्रेसबैक मॉड्यूल ( docs.python.org/library/traceback.html ) से कॉलर के ग्लोबल्स प्राप्त करने का प्रयास कर सकते हैं , लेकिन यह काले जादू के क्षेत्र में हो रहा है। मुझे नहीं पता कि आप क्या करने की कोशिश कर रहे हैं, लेकिन अगर आपको ज़रूरत है तो आप अपने डिज़ाइन पर फिर से विचार कर सकते हैं।
मिकिएज पास्टर्नैकी

"मुझे X की आवश्यकता है (Y करने के लिए) -> आपको X की आवश्यकता नहीं है Z" की आवश्यकता है। हालांकि मुझे X की आवश्यकता है! कोई अपराध नहीं है, मुझे बस यह मनोरंजक लग रहा है, और सबसे अधिक वोट दिया गया जवाब मुझे वह उत्तर देता है जिसकी मुझे आवश्यकता है :)
pawamoy

यह ध्यान रखना महत्वपूर्ण है कि ग्लोबल्स () गलत परिणाम दे सकता है क्योंकि यह उस संदर्भ पर निर्भर करता है जहां कहा जा रहा है। उदाहरण के लिए, यदि किसी वर्ग फ़ंक्शन से कॉल किया जाता है, तो वह क्लास से जुड़े वैश्विक संदर्भ को लौटाएगा, न कि वर्तमान मॉड्यूल संदर्भ को, जो सांकेतिक रूप से अलग बात है। भले ही एक नि: शुल्क फ़ंक्शन से कॉल करें यह एक अलग मॉड्यूल वैश्विक संदर्भ वापस कर सकता है, यह निर्भर करता है कि फ़ंक्शन कैसे आयात किया गया है।
एंड्री

163

जैसा कि पहले उल्लेख किया गया है, ग्लोबल्स आपको डिर () के विपरीत एक शब्दकोश देता है जो आपको मॉड्यूल में परिभाषित नामों की एक सूची देता है। जिस तरह से मैं आमतौर पर यह किया है यह इस तरह है:

import sys
dir(sys.modules[__name__])

2
मैं एक टिप्पणी जोड़ने जा रहा था कि यह ' मुख्य ' मॉड्यूल के लिए काम नहीं करेगा (जो कि टर्मिनल पर चलने वाले मॉड्यूल को कहा जाता है) क्योंकि यह sys.modules में सूचीबद्ध नहीं लगता है - लेकिन यह वास्तव में काम करता है :)
मार्च को

हालाँकि, यह ipdb ("आयात ipdb; ipdb.set_trace ()" को अपनी फ़ाइल में सम्मिलित करने से नहीं लगता है)।
गतोतिग्रादो

9
अति उत्कृष्ट! यह सिर्फ मुझे वर्तमान मॉड्यूल के डॉकस्ट्रिंग को उपयोग संदेश के रूप में उपयोग करने की अनुमति देता है - sys.modules[__name__].__doc__
जॉर्ज

और सुपर हैक करने के लिए। operators.attrgetter('module.attribute')(sys.modules[__name__])- आप जानते हैं, यदि आप पागल चीजें करते हैं, तो लोग आपको बताते हैं कि तार से गतिशील रूप से आयात पैकेज पसंद नहीं करते हैं और फिर बंदर पैच करते हैं, जबकि एक वर्ग या कुछ भी नहीं ...
Casey

2
भूगोल द्वारा टिप्पणी पढ़ने वाले किसी व्यक्ति के लिए: sys.modules[__name__].__doc__== __doc__जैसा कि वर्तमान नामस्थान में परिभाषित किया गया है। मॉड्यूल ऑब्जेक्ट को अपनी विशेषताओं तक पहुंचने के लिए लाना इसलिए आवश्यक नहीं है।
ओलिवर बेस्टवाल्टर

1

उत्तर देने में देर हो सकती है, लेकिन मुझे अपने लिए सही उत्तर नहीं मिला। inspect.stack()अजगर में सबसे निकटतम और सटीक समाधान (से तेज़ ) 3.7.x:

  # search for first module in the stack
  stack_frame = inspect.currentframe()
  while stack_frame:
    print('***', stack_frame.f_code.co_name, stack_frame.f_code.co_filename, stack_frame.f_lineno)
    if stack_frame.f_code.co_name == '<module>':
      if stack_frame.f_code.co_filename != '<stdin>':
        caller_module = inspect.getmodule(stack_frame)
      else:
        # piped or interactive import
        caller_module = sys.modules['__main__']
      if not caller_module is None:
        #... do something here ...
      break
    stack_frame = stack_frame.f_back

पेशेवरों :

  • globals()विधि की तुलना में पूर्ववर्ती ।
  • स्टैक मध्यवर्ती फ़्रेमों पर निर्भर नहीं करता है, जिसे उदाहरण के लिए, हुकिंग के माध्यम से या जैसे कि 3 डी उपकरण द्वारा जोड़ा जा सकता है pytest:
*** foo ... ..
*** boo ... ..
*** runtest c:\python\x86\37\lib\site-packages\xonsh\pytest_plugin.py 58
*** pytest_runtest_call c:\python\x86\37\lib\site-packages\_pytest\runner.py 125
*** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
*** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
*** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
*** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
*** <lambda> c:\python\x86\37\lib\site-packages\_pytest\runner.py 201
*** from_call c:\python\x86\37\lib\site-packages\_pytest\runner.py 229
*** call_runtest_hook c:\python\x86\37\lib\site-packages\_pytest\runner.py 201
*** call_and_report c:\python\x86\37\lib\site-packages\_pytest\runner.py 176
*** runtestprotocol c:\python\x86\37\lib\site-packages\_pytest\runner.py 95
*** pytest_runtest_protocol c:\python\x86\37\lib\site-packages\_pytest\runner.py 80
*** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
*** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
*** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
*** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
*** pytest_runtestloop c:\python\x86\37\lib\site-packages\_pytest\main.py 258
*** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
*** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
*** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
*** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
*** _main c:\python\x86\37\lib\site-packages\_pytest\main.py 237
*** wrap_session c:\python\x86\37\lib\site-packages\_pytest\main.py 193
*** pytest_cmdline_main c:\python\x86\37\lib\site-packages\_pytest\main.py 230
*** _multicall c:\python\x86\37\lib\site-packages\pluggy\callers.py 187
*** <lambda> c:\python\x86\37\lib\site-packages\pluggy\manager.py 86
*** _hookexec c:\python\x86\37\lib\site-packages\pluggy\manager.py 92
*** __call__ c:\python\x86\37\lib\site-packages\pluggy\hooks.py 286
*** main c:\python\x86\37\lib\site-packages\_pytest\config\__init__.py 90
*** <module> c:\Python\x86\37\Scripts\pytest.exe\__main__.py 7
  • अजगर पाइप किए गए या इंटरैक्टिव सत्र को संभाल सकते हैं।

विपक्ष:

  • एक तरह का बहुत सटीक और एक निष्पादन योग्य में पंजीकृत मॉड्यूल लौटा सकता है जैसे कि वह pytest.exeजो आप नहीं चाहते हैं।
  • inspect.getmodule अभी भी हुकिंग के आधार पर मान्य मॉड्यूल पर कोई नहीं लौट सकता है

मेरे पास अजगर का एक विस्तार है: पूर्ण पथ को देखते हुए एक मॉड्यूल को कैसे आयात किया जाए?

विस्तार उस मामले के लिए आवरण कार्य करता है:

def tkl_get_stack_frame_module_by_offset(skip_stack_frames = 0, use_last_frame_on_out_of_stack = False):
  ...

def tkl_get_stack_frame_module_by_name(name = '<module>'):
  ...

आपको एक्सटेंशन को ठीक से इनिशियलाइज़ करना होगा:

# portable import to the global space
sys.path.append(<path-to-tacklelib-module-directory>)
import tacklelib as tkl

tkl.tkl_init(tkl, global_config = {'log_import_module':os.environ.get('TACKLELIB_LOG_IMPORT_MODULE')})

# cleanup
del tkl # must be instead of `tkl = None`, otherwise the variable would be still persist
sys.path.pop()

# use `tkl_*` functions directly from here ...
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.