2012-01-09 12 views
41

से फ़ाइल में गतिशील रूप से एक विधि आयात करें मेरे पास एक स्ट्रिंग है, कहें: abc.def.ghi.jkl.myfile.mymethod। मैं गतिशील रूप से mymethod आयात कैसे करूं?एक स्ट्रिंग

यहाँ कैसे मैं इसके बारे में चला गया है:

def get_method_from_file(full_path): 
    if len(full_path) == 1: 
     return map(__import__,[full_path[0]])[0] 
    return getattr(get_method_from_file(full_path[:-1]),full_path[-1]) 


if __name__=='__main__': 
    print get_method_from_file('abc.def.ghi.jkl.myfile.mymethod'.split('.')) 

मैं अगर आयात करने व्यक्तिगत मॉड्यूल बिल्कुल आवश्यक है सोच रहा हूँ।

संपादित करें: मैं पाइथन संस्करण 2.6.5 का उपयोग कर रहा हूं।

उत्तर

-2

importlib (2.7+ केवल) का उपयोग करें।

+1

मैं 2.6.5 का उपयोग करें। क्या मैं '__future__' चीज़ से' कर सकता हूं? –

+5

नहीं, '__future__' भाषा सुविधाओं के लिए है, न कि नए stdlib मॉड्यूल। – ThiefMaster

+1

ऊपर दिए गए उदाहरणों में बित-इन '__import__' का उपयोग करें। यह 2.5 से पहले और बिना कीवर्ड के, काम करता है। –

17

अजगर < 2.7 निर्मित विधि __ import__ इस्तेमाल किया जा सकता के लिए:

__import__('abc.def.ghi.jkl.myfile.mymethod', fromlist=['']) 

अजगर> = 2.7 या 3.1 सुविधाजनक तरीका importlib.import_module जोड़ दिया गया है के लिए। बस इस तरह अपने मॉड्यूल आयात:

importlib.import_module('abc.def.ghi.jkl.myfile.mymethod') 

अद्यतन: टिप्पणियां (मैं मानता हूं कि मैं स्ट्रिंग पढ़ने नहीं था अंत तक आयात करने के लिए के अनुसार अद्यतन संस्करण और मैं इस तथ्य को याद है कि की एक विधि एक मॉड्यूल आयातित किया जाना चाहिए और नहीं एक मॉड्यूल में ही):

अजगर < 2.7:

mymethod = getattr(__import__("abc.def.ghi.jkl.myfile", fromlist=["mymethod"])) 

अजगर> = 2.7:

mymethod = getattr(importlib.import_module("abc.def.ghi.jkl.myfile"), "mymethod") 
+6

इनमें से कोई भी समाधान काम नहीं करेगा क्योंकि पहला पैरामीटर * __import __() 'और' importlib.import_module() 'दोनों में * मॉड्यूल नाम * होना चाहिए। –

+1

importlib.import_module ('abc.def.ghi.jkl.myfile.mymethod') काम नहीं करेगा क्योंकि आपको "पूर्ण या सापेक्ष शर्तों में आयात करने के लिए कौन सा मॉड्यूल" निर्दिष्ट करना है, और विधि के "योग्य" नाम नहीं। – frm

+0

यह स्पष्ट रूप से काम नहीं करता है, क्योंकि __import__ के पहले पैरामीटर को एक मॉड्यूल होना चाहिए, स्ट्रिंग नहीं। –

21

आप अलग-अलग मॉड्यूल आयात करने की आवश्यकता नहीं है। यह मॉड्यूल आप से एक नाम आयात करना चाहते हैं आयात और fromlist तर्क प्रदान करने के लिए पर्याप्त है:

def import_from(module, name): 
    module = __import__(module, fromlist=[name]) 
    return getattr(module, name) 

अपने उदाहरण abc.def.ghi.jkl.myfile.mymethod के लिए,

import_from("abc.def.ghi.jkl.myfile", "mymethod") 

के रूप में इस फ़ंक्शन को कॉल करें (ध्यान दें कि मॉड्यूल स्तर के कार्यों पाइथन में फ़ंक्शन कहा जाता है, विधियों नहीं।)

इस तरह के एक साधारण कार्य के लिए, importlib मॉड्यूल का उपयोग करने में कोई फायदा नहीं है।

+0

import_from() ने मुझे सही दिशा में इंगित किया। 'myClass = getattr (__ आयात __ (" module.to.import ", सूची = [" myClassName "])," myClassName ")'। सहायता के लिए धन्यवाद! – Fydo

+1

'__import__' दृष्टिकोण काम करता है। लेकिन 'सहायता (__ आयात __)' चलाने का प्रयास करें। यह कहता है "चूंकि यह फ़ंक्शन पायथन दुभाषिया द्वारा उपयोग के लिए है और सामान्य उपयोग के लिए नहीं, तो 'importlib.import_module()' को प्रोग्रामेटिक रूप से मॉड्यूल आयात करने के लिए बेहतर है। " – twasbrillig

+2

@twasbrillig: जब मैंने इस सवाल का जवाब दिया, तो पाइथन 2.5 और 2.6 अभी भी व्यापक रूप से उपयोग में थे। आज, इसके बजाय 'importlib' का उपयोग करना निश्चित रूप से सर्वोत्तम है। –

57

पायथन 2.7 से आप importlib.import_module() फ़ंक्शन का उपयोग कर सकते हैं। आप एक मॉड्यूल आयात और निम्न कोड के साथ एक वस्तु के भीतर परिभाषित पहुंच सकता है: जिस तरह से मैं यह करने के लिए करते हैं (और साथ ही इस तरह के तोरणों और पेस्ट के रूप में अन्य पुस्तकालयों, के एक नंबर,

from importlib import import_module 

p, m = name.rsplit('.', 1) 

mod = import_module(p) 
met = getattr(mod, m) 

met() 
+0

पाइथन दस्तावेज़ों को ध्यान में रखते हुए मूल्य '__import __()' पर 'importlib.import_module()' का उपयोग करने की सलाह देते हैं: https://docs.python.org/2/library/functions.html#__import__ - 2.7+ के लिए। – BoltzmannBrain

+2

'import_module' ** + **' rsplit' ** = ** _ एक सही तरीका ._ –

0

मेरी स्मृति अगर मुझे सही ढंग से सेवा करता है) मॉड्यूल नाम को उनके बीच ':' का उपयोग करके फ़ंक्शन/विशेषता नाम से अलग करना है। निम्नलिखित उदाहरण देखें:

'abc.def.ghi.jkl.myfile:mymethod'

यह उपयोग में आसान एक छोटे से नीचे import_from(path) समारोह में आता है।

def import_from(path): 
    """ 
    Import an attribute, function or class from a module. 
    :attr path: A path descriptor in the form of 'pkg.module.submodule:attribute' 
    :type path: str 
    """ 
    path_parts = path.split(':') 
    if len(path_parts) < 2: 
     raise ImportError("path must be in the form of pkg.module.submodule:attribute") 
    module = __import__(path_parts[0], fromlist=path_parts[1]) 
    return getattr(module, path_parts[1]) 


if __name__=='__main__': 
    func = import_from('a.b.c.d.myfile:mymethod') 
    func() 
+1

कोई भी ऐसा क्यों नहीं करना चाहिए? इसके लिए कॉलर को मॉड्यूल नाम और एक कोलन के साथ विशेषता नाम में शामिल होने की आवश्यकता होती है, और फ़ंक्शन को कोलन पर फिर से विभाजित करने की आवश्यकता होती है। क्यों न केवल दो पैरामीटर का उपयोग पहली जगह में करें? –

+0

अक्सर, ऐसी स्थिति जहां यह आ जाएगा, अगर आप विन्यास फाइलों (.yaml, .ini, आदि) का उपयोग कर अपने आवेदन में ढांचे से कॉलबैक तार करते हैं। फिर, आप निर्दिष्ट कर सकते हैं कि फ्रेमवर्क को कौन सा फ़ंक्शन कॉल करना चाहिए, इत्यादि, अपनी कॉन्फ़िगरेशन फ़ाइल में एक स्ट्रिंग के साथ। –

+0

अच्छा, हाँ, आप इसे कॉन्फ़िगरेशन फ़ाइल सिंटैक्स के रूप में चुनना चाहेंगे। लेकिन यह ओपी के सवाल से कैसे संबंधित है? (और अगर मैंने इसे अपनी कॉन्फ़िगरेशन फ़ाइल सिंटैक्स के रूप में चुना है, तो भी मैं इसे अपने कॉन्फ़िगरेशन फ़ाइल पार्सर द्वारा पार्स करना चाहता हूं, यादृच्छिक API फ़ंक्शंस द्वारा नहीं।) –

3

यह स्पष्ट नहीं है कि आप अपने स्थानीय नामस्थान में क्या करने का प्रयास कर रहे हैं। मुझे लगता है कि आप my_method स्थानीय के रूप में output = my_method() टाइप करना चाहते हैं?

# This is equivalent to "from a.b.myfile import my_method" 
the_module = importlib.import_module("a.b.myfile") 
same_module = __import__("a.b.myfile") 
# import_module() and __input__() only return modules 
my_method = getattr(the_module, "my_method") 

# or, more concisely, 
my_method = getattr(__import__("a.b.myfile"), "my_method") 
output = my_method() 

आप केवल स्थानीय नाम स्थान के लिए my_method जोड़ने के दौरान, आप मॉड्यूल की श्रृंखला लोड है। आप आयात से पहले और बाद में sys.modules की चाबियाँ देखकर परिवर्तन देख सकते हैं। मुझे उम्मीद है कि यह आपके अन्य उत्तरों की तुलना में स्पष्ट और अधिक सटीक है।

पूर्णता के लिए, इस तरह आप पूरी श्रृंखला जोड़ते हैं।

# This is equivalent to "import a.b.myfile" 
a = __import__("a.b.myfile") 
also_a = importlib.import_module("a.b.myfile") 
output = a.b.myfile.my_method() 

# This is equivalent to "from a.b import myfile" 
myfile = __import__("a.b.myfile", fromlist="a.b") 
also_myfile = importlib.import_module("a.b.myfile", "a.b") 
output = myfile.my_method() 

और अंत में, यदि आप __import__() का उपयोग कर रहे हैं और आप पथ खोज के बाद कार्यक्रम शुरू कर दिया संशोधित किया है, तो आप __import__(normal args, globals=globals(), locals=locals()) उपयोग करने की आवश्यकता हो सकती है। एक जटिल चर्चा क्यों है।

+0

'the_module' और 'same_module' का आपका पहला उदाहरण गलत है और विभिन्न परिणाम उत्पन्न करें। Downvoting। – sleepycal

0

इस वेबसाइट पर एक अच्छा समाधान है: load_class। मैं इसे इस तरह का उपयोग करें:

foo = load_class(package.subpackage.FooClass)() 
type(foo) # returns FooClass 
1
from importlib import import_module 


name = "file.py".strip('.py') 
# if Path like : "path/python/file.py" 
# use name.replaces("/",".") 

imp = import_module(name) 

# get Class From File.py 
model = getattr(imp, "naemClassImportFromFile") 

NClass = model() # Class From file