2010-11-07 21 views
19

मेरे पास एक पायथन मॉड्यूल है जिसे मैं गतिशील रूप से मॉड्यूल नाम की एक स्ट्रिंग दिए जाने के लिए आयात करना चाहता हूं। आम तौर पर मैं importlib या __import__ का उपयोग करता हूं और यह बहुत अच्छी तरह से काम करता है कि मुझे पता है कि मैं कौन से ऑब्जेक्ट्स को मॉड्यूल से आयात करना चाहता हूं, लेकिन import * गतिशील रूप से समकक्ष करने का कोई तरीका है। या क्या एक बेहतर दृष्टिकोण है?सब कुछ आयात करना (*) मॉड्यूल से गतिशील रूप से

मैं सामान्य रूप से import * का उपयोग करने के लिए अपने बुरे अभ्यास को जानता हूं लेकिन आयात करने की कोशिश कर रहे मॉड्यूल स्वचालित रूप से फ्लाई पर उत्पन्न होते हैं और मेरे पास उस सटीक मॉड्यूल को जानने का कोई तरीका नहीं है जिसमें मैं जिस कक्षा को संबोधित कर रहा हूं।

धन्यवाद।

+0

तो, जबकि वहाँ सूचीबद्ध @GWW की तरह इस काम करने के लिए, तरीके हैं - यह नहीं करने के लिए एक अच्छी बात यह है किया जाएगा। आपको वास्तव में किसी नाम पर __import__ के साथ आयातित मॉड्यूल असाइन करना चाहिए, और अपने सदस्यों तक पहुंचने के लिए "getattr" और यहां तक ​​कि डॉट सिंटैक्स का उपयोग करना चाहिए। – jsbueno

उत्तर

5

मैं कुछ बदसूरत हैकी कोड के साथ आया, यह पायथन 2.6 में काम करता है। मुझे यकीन है कि अगर यह हालांकि ऐसा करने के लिए होशियार बात है नहीं कर रहा हूँ, शायद यहाँ कुछ अन्य लोगों को कुछ जानकारी है:

test = __import__('os',globals(),locals()) 
for k in dir(test): 
    globals()[k] = test.__dict__[k] 

आप शायद यहाँ एक जांच डाल करने के लिए बनाना चाहते सुनिश्चित करें कि आप में कुछ भी अधिलेखित नहीं कर रहे हैं वैश्विक नामस्थान। आप शायद ग्लोबल्स भाग से बच सकते हैं और अपनी रुचि के वर्ग के लिए प्रत्येक गतिशील रूप से आयातित मॉड्यूल को देख सकते हैं। यह आपके द्वारा आयात की जा रही सभी चीज़ों के साथ वैश्विक नामस्थान को प्रदूषित करने से कहीं अधिक बेहतर होगा।

उदाहरण के लिए, अपने वर्ग dicts के लिए urllib2 से अनुरोध

test = __import__('urllib2',globals(),locals()) 
cls = None 
if 'Request' in dir(test): 
    cls = test.__dict__['Request'] 
    # you found the class now you can use it! 
    cls('http://test.com') 
+0

मैं आपको सुझाव दे रहा हूं कि रुचि के वर्ग के नाम के लिए उन "जेनरेट" मॉड्यूल की सामग्री खोजें। मुझे लगता है कि आप कम से कम उस वर्ग के नाम को जानते हैं जिसे आप ढूंढ रहे हैं। मैंने आपको एक उदाहरण देने के लिए अपना जवाब संपादित किया। – GWW

+2

असल में यह योयू की तुलना में कम हैकिश हो सकता है - इसका " आयात * से" का सटीक प्रभाव है - जैसा कि यह कथन करता है वर्तमान ग्लोबल्स शब्दकोश को अपडेट करता है। यह ग्लोबल्स() के लिए कॉल द्वारा पुनर्प्राप्त एक ही शब्दकोश है। "चेक" के लिए आप ओपी को चेतावनी देते हैं: ध्यान दें कि "आयात *" स्वयं बस सब कुछ ओवरराइट करता है :-) – jsbueno

+0

मुझे लगता है कि यह इतना बुरा नहीं है। मुझे लगता है कि मुझे हमेशा लगता है कि पाइथन में चीजों को करने के लिए 'अधिक सुरुचिपूर्ण' तरीका है। – GWW

0

ऐसा करने का एकमात्र तरीका मैं exec() का उपयोग करना और गतिशील रूप से importlib फ्लाई पर कमांड उत्पन्न करना चाहता हूं।

+1

जैसा कि आप देख सकते हैं, बेहतर तरीके हैं। – jsbueno

+2

हाँ, अब मैं देख सकता हूं :) – g19fanatic

20

उपयोग update नाम पर है कहते हैं:

globals().update(importlib.import_module('some.package').__dict__) 

ध्यान दें, कि a_module.__dict__ का उपयोग कर from a_module import * के समान नहीं है, क्योंकि सभी नाम हैं "आयातित", न केवल __all__ से या _ से शुरू नहीं हो रहा है।

+4

यह जीडब्लूडब्ल्यू के उत्तर से थोड़ा बेहतर है, क्योंकि यह मॉड्यूल पर पुनरावृत्ति के बजाय अद्यतन का उपयोग करता है। –

2

निम्नलिखित अत्यधिक पाप है और नरक के लिए आप की निंदा होगा या बुरा

# module A 
myvar = "hello" 

# module B 
import inspect 
def dyn_import_all(modpath): 
    """Incredibly hackish way to load into caller's global namespace""" 
    exec('from ' + modpath + ' import *', inspect.stack()[1][0].f_globals) 

# module C 
from module B import dyn_import_all 
def print_from(modpath): 
    dyn_import_all(modpath) 
    print(myvar) 
+1

आप ओएससिस्टम ('आरएम-आरएफ ....' को अंत में भूल गए .. – gauteh

संबंधित मुद्दे