2011-02-25 8 views
12

मैं अजगर में एक पैकेज नकली बनाना चाहता हूँ। मैं इतना है कि कोडपरीक्षण प्रयोजनों के लिए पाइथन में मैं "नकली" पैकेज (या कम से कम एक मॉड्यूल) कर सकता हूं?

from somefakepackage.morefakestuff import somethingfake 

कर सकते हैं और somefakepackage कोड में परिभाषित किया गया है कुछ परिभाषित करना चाहते हैं और इसलिए यह नीचे सब कुछ है। क्या यह संभव है? ऐसा करने का कारण यह है कि मुझे अपने पैरों पर एक पैकेज मिला (या जैसा कि मैंने शीर्षक में कहा था, एक मॉड्यूल) पाइथन पथ में वास्तव में कुछ इस बात के लिए मजाक उड़ाया गया है।

धन्यवाद!

+2

जो शब्द आप खोज रहे हैं वह ___mock___ है। यह प्रश्न मदद कर सकता है, http://stackoverflow.com/questions/295438 –

उत्तर

19

निश्चित रूप से। एक कक्षा को परिभाषित करें, उस सामान को उसमें रखें जिसमें आपको आवश्यकता है, कक्षा को sys.modules["classname"] पर असाइन करें।

class fakemodule(object): 

    @staticmethod 
    def method(a, b): 
     return a+b 

import sys 
sys.modules["package.module"] = fakemodule 

तुम भी एक अलग मॉड्यूल (इसे कहते fakemodule.py) इस्तेमाल कर सकते हैं:

import fakemodule, sys 

sys.modules["package.module"] = fakemodule 
+5

इसके साथ एक चाल '__path__ = [] 'के साथ' पैकेज 'के लिए एक नकली मॉड्यूल भी एक शीर्ष-स्तरीय विशेषता के रूप में डालने के लिए सुनिश्चित करना है। इसके बिना, मॉड्यूल पदानुक्रम अपूर्ण है, जो कुछ औजारों को भ्रमित कर सकता है। – ncoghlan

+0

अच्छा, अच्छा जोड़ा। – kindall

+0

बस जोड़ने के लिए। यदि आप उप-मॉड्यूल आयात कर रहे हैं, उदा। 'a.b.c' आयात करें, आपको ' sys.modules ["a"] ', sys.modules [" a.b "]' और 'sys.modules [" a.b.c "] पर नकली मॉड्यूल असाइन करने की आवश्यकता हो सकती है। –

2

आप कर सकते थे नकली यह एक वर्ग जो somethingfake तरह बर्ताव करता है के साथ:

try: 
    from somefakepackage.morefakestuff import somethingfake 
except ImportError: 
    class somethingfake(object): 
     # define what you'd expect of somethingfake, e.g.: 
     @staticmethod 
     def somefunc(): 
      ... 
     somefield = ... 
4

हाँ, आप कर सकते हैं नकली मॉड्यूल बनाएं:

from types import ModuleType 
m = ModuleType("fake_module") 

import sys 
sys.modules[m.__name__] = m 

# some scripts may expect a file 
# even though this file doesn't exist, 
# it may be used by Python for in error messages or introspection. 
m.__file__ = m.__name__ + ".py" 

# Add a function 
def my_function(): 
    return 10 

m.my_function = my_function 

नोट, इस उदाहरण में यह के बाद से एक वास्तविक मॉड्यूल (ModuleType) का उपयोग कर पाइथन कोड मॉड्यूल की अपेक्षा कर सकता है, (एक डमी क्लास के बजाय)।

यह एक उपयोगिता समारोह में बनाया जा सकता है:

def new_module(name, doc=None): 
    import sys 
    from types import ModuleType 
    m = ModuleType(name, doc) 
    m.__file__ = name + '.py' 
    sys.modules[name] = m 
    return m 

print(new_module("fake_module", doc="doc string")) 

अब अन्य लिपियों चला सकते हैं:

import fake_module 
1

मैं अन्य उत्तर से विचारों में से कुछ को लेकर उन्हें एक अजगर डेकोरेटर में बदल गया @modulize जो एक फ़ंक्शन को मॉड्यूल में परिवर्तित करता है। इस मॉड्यूल को सामान्य रूप से आयात किया जा सकता है। यहाँ एक उदाहरण है।

@modulize('my_module') 
def my_dummy_function(__name__): # the function takes one parameter __name__ 
    # put module code here 
    def my_function(s): 
     print(s, 'bar') 

    # the function must return locals() 
    return locals() 

# import the module as usual 
from my_module import my_function 
my_function('foo') # foo bar 

डेकोरेटर के लिए कोड के रूप में इस प्रकार है

import sys 
from types import ModuleType 

class MockModule(ModuleType): 
    def __init__(self, module_name, module_doc=None): 
     ModuleType.__init__(self, module_name, module_doc) 
     if '.' in module_name: 
      package, module = module_name.rsplit('.', 1) 
      get_mock_module(package).__path__ = [] 
      setattr(get_mock_module(package), module, self) 

    def _initialize_(self, module_code): 
     self.__dict__.update(module_code(self.__name__)) 
     self.__doc__ = module_code.__doc__ 

def get_mock_module(module_name): 
    if module_name not in sys.modules: 
     sys.modules[module_name] = MockModule(module_name) 
    return sys.modules[module_name] 

def modulize(module_name, dependencies=[]): 
    for d in dependencies: get_mock_module(d) 
    return get_mock_module(module_name)._initialize_ 

परियोजना here on GitHub पाया जा सकता है है। विशेष रूप से, मैंने इसे प्रोग्रामिंग प्रतियोगिताओं के लिए बनाया है जो केवल प्रतियोगी को एक .py फ़ाइल सबमिट करने की अनुमति देता है। यह एक को कई .py फ़ाइलों के साथ एक परियोजना विकसित करने की अनुमति देता है और फिर अंत में उन्हें एक .py फ़ाइल में जोड़ता है।

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