2012-05-24 24 views
7

मैं एक फ़ंक्शन के वास्तविक वर्तमान मॉड्यूल को निर्धारित करने की कोशिश कर रहा हूं (जैसा कि अन्यत्र से आयात किया गया है), भले ही वर्तमान मॉड्यूल "top level scripting environment" __main__ है।पायथन: वास्तविक वर्तमान मॉड्यूल निर्धारित करें (__main__ नहीं)

यह एक अजीब चीज की तरह लग सकता है, लेकिन पृष्ठभूमि यह है कि मुझे एक फ़ंक्शन को क्रमबद्ध करने और एक अलग मशीन पर इसे तर्कसंगत बनाने (तर्क सहित) की आवश्यकता होती है, जिसके लिए मुझे सही मॉड्यूल सुनिश्चित करना होगा और __main__ deserializing से पहले आयात किया जाता है (अन्यथा मुझे AttributeError: 'module' object has no attribute my_fun कहने में त्रुटि मिलती है)।

अब तक, मैं inspection की कोशिश की है:

import inspect 
print inspect.getmodule(my_fun) 

जो मुझे

<module '__main__' from 'example.py'> 
निश्चित रूप से

देता है। मैंने globals() का उपयोग करके कुछ उपयोगी खोजने की भी कोशिश की, कोई भाग्य नहीं।

मैं वास्तव में क्या चाहता हूं <module 'example' from 'example.py'> है। मुझे लगता है कि जिस तरह से एक hacky तरह

m_name = __main__.__file__.split("/")[-1].replace(".pyc","") 

कुछ का उपयोग कर फ़ाइल नाम से यह पार्स करने के लिए और उसके बाद नाम sys.modules[m_name] द्वारा मॉड्यूल को खोजने के लिए होगा।

क्या ऐसा करने के लिए एक क्लीनर/बेहतर तरीका है?

संपादित करें: IPython के "FakeModule" और थोड़ा अधिक Googling के बारे में सीखने के बाद, मैं जो वास्तव में समस्या यह है कि मैं, का सामना करना पड़ रहा है यह करने के लिए मेरे वर्तमान समाधान (जो स्पष्ट रूप से वर्तमान मॉड्यूल आयात कर रहा है सहित वर्णन करता this post करवाते आया था, import current_module और my_fun के बजाय current_module.my_fun क्रमबद्ध करना)। मैं इससे बचने की कोशिश कर रहा हूं, क्योंकि यह मेरे पैकेज के उपयोगकर्ताओं के लिए सहज नहीं हो सकता है।

+0

क्या आपने पहले 'आयातक' मॉड्यूल से पहले 'नाक' लाइब्रेरी के आंतरिक भाग को देखा है? 'नाक' कुछ चीजें इस तरह के समान है, इसलिए यह प्रेरणा की तलाश में एक अच्छी जगह हो सकती है। –

उत्तर

3

मैं वास्तव में इसी समस्या से भाग गया।

मैं क्या इस्तेमाल किया गया था:

return os.path.splitext(os.path.basename(__main__.__file__))[0] 

प्रभावी रूप से के रूप में अपने ही है कौन सा "हैक।" ईमानदारी से, मुझे लगता है कि यह सबसे अच्छा समाधान है।

+0

धन्यवाद विंस्टन, यह वह समाधान है जिसके साथ मैं गया था और मैंने तब से किसी भी ग़लत समस्या में भाग नहीं लिया है। – soramimo

+0

यदि आप किसी फ़ोल्डर के अंदर अपनी स्क्रिप्ट चला रहे हैं, तो यह काम नहीं करता है, उदाहरण के लिए, "बार/foo.py" – jwayne

+0

@jwayne, इसके बजाय यह क्या उत्पादन करता है? –

2

एक तरीका यह है कि आप यह कर सकते हैं - संभवतः यह सबसे अच्छा तरीका नहीं है, लेकिन यह मेरे लिए काम करता है - __import__ के साथ अपने मॉड्यूल आयात करना और getattr का उपयोग निम्न प्रकार की तरह से करें।

(यहाँ मैं this post मॉड्यूल के बारे में गतिशील रूप से लोड हो रहा है में वर्णित कुछ विचारों का उपयोग कर रहा हूँ।)

def dynamic_import(name): 
    mod = __import__(name) 
    components = name.split('.') 
    for comp in components[1:]: 
     mod = getattr(mod, comp) 
    return mod 

tmodule = dynamic_import('modA') 
# Print the module name 
print tmodule 
# Use the module's contents 
t = tmodule.myObject() 
t.someMethod() 

कहाँ modA.py इस तरह दिखता है:

class myObject(): 
    def someMethod(self): 
     print "I am module A" 

तो तुम हम मिल रहे हैं देख सकते हैं मॉड्यूल का नाम जिसे हमने आयात किया है और अभी भी सामान्य तरीके से मॉड्यूल के अंदर ऑब्जेक्ट्स और विधियों का उपयोग करना है। जब मैं इस चलाने मैं निम्नलिखित मिल:

python experiment.py 
<module 'modA' from 'modA.pyc'> 
I am module A 

'आदर्श' जिस तरह से फिर, यह या नहीं हो सकता है, लेकिन यह अच्छी तरह से और जहाँ तक मैं बता अधिकांश में किसी भी अवांछनीय समझौतों से आवश्यक नहीं है कर सकते हैं काम करता है मामलों। उम्मीद है की यह मदद करेगा।

3

मुझे लगता है कि आपका मूल समाधान सबसे अच्छा और सरल है। यदि आप इसके बारे में चिंतित हैं, तो यह आपके उपयोगकर्ताओं के लिए काउंटर-अंतर्ज्ञानी प्रतीत होता है, इसे एक अच्छे फ़ंक्शन में लपेटें और दस्तावेज़ के लिए क्या करें।

जब आप __main__ के रूप में मॉड्यूल चलाते हैं, तो पाइथन वास्तव में इसे अपने सामान्य मॉड्यूल नाम से संबद्ध नहीं करता है: यदि आप import example हैं, तो यह फ़ाइल को दूसरी बार लोड करेगा जैसे कि यह एक अलग मॉड्यूल है। असल में यह संभवतः आपके मामले में होता है, अन्यथा आप sys.modules में नाम से अपना मॉड्यूल नहीं ढूंढ पाएंगे: मॉड्यूल example और मॉड्यूल __main__ वास्तव में अलग रनटाइम ऑब्जेक्ट्स हैं, क्योंकि आप पाएंगे कि क्या आप स्पष्ट रूप से मॉड्यूल चर बदलते हैं उनमें से एक।

3

मुझे पता है कि यह पुराना है लेकिन मुझे पाइथन 3 में एक आसान समाधान मिला जो मेरे लिए काम करता था। लंबी कहानी छोटी है, ऑब्जेक्ट का __spec__ है जो "__main__" होने के बजाय वास्तविक मॉड्यूल नाम भी संग्रहीत करता है।

import inspect 
if obj.__class_.__module__ == "__main__": 
    print(inspect.getmodule(obj).__spec__.name) 
+0

यह मॉड्यूल के रूप में चलने पर ही काम करता है ('python -m' के साथ), अन्यथा' __spec__' 'none' है। लेकिन यह मेरे लिए काफी अच्छा है! (इसके अलावा, मेरे उपयोग के मामले में, मैं 'निरीक्षण' छोड़ सकता हूं और बस 'आयात __main__; प्रिंट (__ मुख्य __.__ spec __। नाम) का उपयोग कर सकता हूं।) –