2012-07-28 20 views
11

मेरे कुछ Django ऐप्स में मैं विभिन्न वातावरण (जैसे विकास, परीक्षण और उत्पादन) पर अलग-अलग सेटिंग्स को ओवरराइड करने के लिए settings_local.py फ़ाइल का उपयोग कर रहा हूं। मैं मूल रूप से निम्नलिखित कोड का इस्तेमाल किया है settings.py में इसकी सामग्री शामिल करने के लिए:पायथन: 'आयात *' बनाम execfile

try: 
    from settings_local import * 
except ImportError: 
    sys.stderr.write("The settings_local.py file is missing.\n") 
    DEBUG=False 

मैं हाल ही में execfile समारोह पाया है और की तरह कुछ करने के लिए बंद कर:

try: 
    execfile(path.join(PROJECT_ROOT, "settings_local.py")) 
except IOError: 
    sys.stderr.write("The settings_local.py file is missing.\n" 
    DEBUG=False 

दोनों काम के रूप में इरादा है, लेकिन मैं मैं उत्सुक हूं कि मुझे कोई गॉथस याद आ रहा है, और सामान्य रूप से कौन सा दृष्टिकोण अधिक अनुशंसित है और क्यों।

उत्तर

14

execfile फ़ंक्शन का उपयोग करने से प्रत्येक बार सेटिंग फ़ाइल का मूल्यांकन किया जाता है, तो पाइथन स्रोत फ़ाइल (.py) का मूल्यांकन किया जाएगा। आप प्रत्येक बार पाइथन पार्सर निष्पादित कर रहे हैं। import का उपयोग करना आवश्यक नहीं होगा (.pyc फ़ाइल का उपयोग कर सकते हैं)। आम तौर पर पहली बार जब आप पाइथन (कम से कम, सीपीथन) में एक प्रोजेक्ट चलाते हैं तो यह बाइटकोड में संकलित हो जाता है और दोबारा नहीं बदला जाता है। आप इसे तोड़ रहे हैं। यह एक समस्या नहीं है, लेकिन आपको इसके बारे में पता होना चाहिए।

execfile का उपयोग करने से settings_local.py फ़ाइल में आपके सभी आयातों का परिणाम settings.py फ़ाइल के मॉड्यूल स्कोप में फिर से मूल्यांकन किया जा रहा है। import * का उपयोग करके settings_local.py मॉड्यूल स्कोप में सभी आइटम शामिल होंगे। शुद्ध प्रभाव वही है (settings_local.py मॉड्यूल स्कोप में शामिल सभी आइटम settings.py में शामिल हैं) लेकिन विधि अलग है।

अंत में, मॉड्यूल के लिए मॉड्यूल के रूप में निष्पादित किया जाना सामान्य है। कोड के लिए os.path.dirname(__file__) जैसी चीज़ों को शामिल करना उचित है। यदि किसी भी कोड ने इसका उपयोग किया है, तो आप इसे भ्रमित कर देंगे क्योंकि कोड मॉड्यूल में अब निष्पादित नहीं होगा जिसे लेखक ने उचित रूप से अपेक्षित किया है।

मेरे अनुभव में, लोग importexecfile का उपयोग नहीं करते हैं। Django बहुत अधिक 'कॉन्फ़िगरेशन पर सम्मेलन' है। सम्मेलन का पालन करें।

+5

'__file__' आसानी से तर्कों के माध्यम से प्रदान किया जा सकता है। मुख्य अंतर यह है कि मॉड्यूल को एक बार आयात किया जाता है इससे कोई फर्क नहीं पड़ता कि 'आयात मॉड्यूल' कितनी बार निष्पादित किया जाता है ('exec' फ़ाइल को हर बार फ़ाइल निष्पादित करता है), और 'आयात' को फ़ाइल के स्पष्ट पथ की आवश्यकता नहीं होती है (तो यह भी एक ज़िप संग्रह के अंदर काम करेगा)। – jfs

+0

@ जेएफ। सेबेस्टियन यह एक जवाब होना चाहिए। – Marcin

+3

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

2

पहला संस्करण (from settings_local import *) वह है जो सभी को देखने की उम्मीद है। यह कोड विश्लेषक मॉड्यूल को भी ढूंढने देगा।

8

एक और अंतर: execfile को संदर्भ शब्दकोश मिलता है; डिफ़ॉल्ट संदर्भ या एक निर्दिष्ट शब्दकोश द्वारा वैश्विक संदर्भ।

# Probably not a good thing to do 
z=x+1 # an expression that involves an un-defined field 

जाहिर है,

from dont_do_this import * 

विफल रहता है: यह कुछ अजीब बातें

dont_do_this.py अनुमति दे सकता है।

हालांकि,

d={'x':1} 
execfile('dont_do_this.py', d) 

ठीक है और में d=={'x':1, 'z':2}

नोट परिणाम है कि

x=1 
execfile('dont_do_this.py') 

ठीक है और चर z में परिणाम वैश्विक में जोड़ा जा रहा।

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