2011-11-22 6 views
5

मैं एक पायथन फ़ंक्शन लिखता हूं जैसे तारों को प्रतिस्थापित करना और स्कैन स्क्रिप्ट में कॉल करना।स्कॉन्स: स्कैन स्क्रिप्ट में एक स्व परिभाषित पायथन फ़ंक्शन को कैसे कॉल करें और सही निर्भरता

def Replace(env, filename, old, new): 
    with open(filename,"r+") as f: 
    d = f.read() 
    d = d.replace(old, new) 
    f.truncate(0) 
    f.seek(0) 
    f.write(d) 
    f.close() 
env.AddMethod(Replace,'Replace') 

SConscript

lib = env.SharedLibrary('lib', object, extra_libs) 
tmp = env.Command([],[],[env.Replace(somefile, 'A', 'b')]) 
env.Depends(tmp,lib) 

मैं क्या उम्मीद में बनाया lib के बाद बदलें() विधि को चलाने के लिए है। लेकिन स्कॉन्स हमेशा पहले राउंड स्क्रिप्ट पार्सिंग वाक्यांश में रीप्लेस() चलाते हैं। ऐसा लगता है कि मुझे कुछ निर्भरता याद आ रही है।

उत्तर

4

मुझे विश्वास है कि आप शायद builders that execute python functions खोज रहे हैं।

मुश्किल बात यह है कि स्कॉन्स वास्तव में जिस तरह से आप इसे मजबूर कर रहे हैं, उस पर काम नहीं करना चाहते हैं। क्रियाएं दोहराने योग्य और विनाशकारी होनी चाहिए, आपके कोड में आप वास्तव में somefile की मूल सामग्री को नष्ट कर रहे हैं। इसके बजाय, आप एक ही परिणाम प्राप्त करने के लिए लक्ष्य/स्रोत प्रतिमान और किसी प्रकार की टेम्पलेट फ़ाइल का उपयोग कर सकते हैं।

import os 
import re 

def replace_action(target, source, env): 
    # NB. this is a pretty sloppy way to write a builder, but 
    #  for things that are used internally or infrequently 
    #  it should be more than sufficient 
    assert(len(target) == 1) 
    assert(len(source) == 1) 
    srcf = str(source[0]) 
    dstf = str(target[0]) 
    with open(srcf, "r") as f: 
     contents = f.read() 
     # In cases where this builder fails, check to make sure you 
     # have correctly added REPLST to your environment 
     for old, new in env['REPLST']: 
      contents = re.sub(old, new, contents) 
     with open(dstf, "w") as outf: 
      outf.write(contents) 

replace_builder = Builder(action = replace_action) 

env = Environment(ENV = os.environ) 
env.Append(BUILDERS = {'Replace' : replace_builder }) 
b = env.Replace('somefile', ['somefile.tmpl'], REPLST=[('A','b')]) 
lib = env.SharedLibrary('lib', object + [b], extra_libs) 

नोट है कि मेरे परीक्षण में, की जगह समारोह बहु लाइन डेटा के साथ अच्छी तरह से नहीं खेल रहा था, इसलिए मैं सिर्फ पूर्ण नियमित अभिव्यक्ति (re.sub) का उपयोग करने के लिए बदली है। यह शायद धीमा है, लेकिन काफी अधिक लचीलापन प्रदान करता है।

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