2009-09-01 14 views
10

मेरे पास ऑब्जेक्ट्स का एक समूह है जिसे मैं कक्षा बना रहा हूं, मैं प्रत्येक ऑब्जेक्ट को अपनी टेक्स्ट फ़ाइल के रूप में स्टोर करना चाहता हूं। मैं वास्तव में इसे एक पायथन कक्षा परिभाषा के रूप में संग्रहीत करना चाहता हूं जो मुख्य वर्ग को बना रहा है जो मैं बना रहा हूं। तो, मैंने कुछ पोकिंग किया और effbot.org पर पाइथन कोड जेनरेटर पाया। मैं कुछ इसे के साथ प्रयोग किया है और यहाँ क्या मैं के साथ आया है:पायथन उत्पन्न पाइथन

# 
# a Python code generator backend 
# 
# fredrik lundh, march 1998 
# 
# [email protected] 
# http://www.pythonware.com 
# 
# Code taken from http://effbot.org/zone/python-code-generator.htm 

import sys, string 

class CodeGeneratorBackend: 

    def begin(self, tab="\t"): 
     self.code = [] 
     self.tab = tab 
     self.level = 0 

    def end(self): 
     return string.join(self.code, "") 

    def write(self, string): 
     self.code.append(self.tab * self.level + string) 

    def indent(self): 
     self.level = self.level + 1 

    def dedent(self): 
     if self.level == 0: 
      raise SyntaxError, "internal error in code generator" 
     self.level = self.level - 1 

class Point(): 
    """Defines a Point. Has x and y.""" 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    def dump_self(self, filename): 
     self.c = CodeGeneratorBackend() 
     self.c.begin(tab=" ") 
     self.c.write("class {0}{1}Point()\n".format(self.x,self.y)) 
     self.c.indent() 
     self.c.write('"""Defines a Point. Has x and y"""\n') 
     self.c.write('def __init__(self, x={0}, y={1}):\n'.format(self.x, self.y)) 
     self.c.indent() 
     self.c.write('self.x = {0}\n'.format(self.x)) 
     self.c.write('self.y = {0}\n'.format(self.y)) 
     self.c.dedent() 
     self.c.dedent() 
     f = open(filename,'w') 
     f.write(self.c.end()) 
     f.close() 

if __name__ == "__main__": 
    p = Point(3,4) 
    p.dump_self('demo.py') 

यह वास्तव में बदसूरत लगता है, वहाँ एक क्लीनर/बेहतर/अधिक pythonic यह करने के लिए तरीका है? कृपया ध्यान दें, यह वह कक्षा नहीं है जिसका मैं वास्तव में ऐसा करने का इरादा रखता हूं, यह एक छोटी सी कक्षा है जिसे मैं आसानी से कई लाइनों में नकल नहीं कर सकता हूं। साथ ही, उप-वर्गों में उन्हें उत्पन्न करने की आवश्यकता नहीं है, अगर मुझे दोबारा ज़रूरत है, तो मैं सिर्फ सुपर जेनरेटर से कोड जनरेटर को कॉल कर सकता हूं।

+0

इंडेंट पायथन में टैब का उपयोग न करें, रिक्त स्थान का उपयोग करें :) –

+0

हाँ, यह डिफ़ॉल्ट के रूप में सेट करता है, लेकिन मैं उस चर w/4 रिक्त स्थान को ओवरराइट करता हूं। – Jonathanb

उत्तर

22

हम टेम्पलेट भरने के लिए Jinja2 का उपयोग करते हैं। यह बहुत आसान है।

टेम्पलेट कुछ {{something}} प्रतिस्थापन के साथ पाइथन कोड की तरह दिखता है।

+0

एनन को मेरी टिप्पणी के अनुसार, मैं सिर्फ एक टेम्पलेट सिस्टम का उपयोग करने जा रहा हूं। मैं जिन्जा में बारीकी से देख रहा हूं, टिप के लिए धन्यवाद! – Jonathanb

+2

इसका कोई उदाहरण है? – KJW

+0

यह करने का यह एक शानदार तरीका है! – specialscope

5

यह पाइथन स्रोत कोड उत्पन्न करने का सबसे अच्छा तरीका है। हालांकि, आप ast लाइब्रेरी का उपयोग कर रनटाइम पर पायथन निष्पादन योग्य कोड भी उत्पन्न कर सकते हैं। (मैंने पायथन 3 संस्करण से जुड़ा हुआ है क्योंकि यह 2.x संस्करण से अधिक सक्षम है।) आप अमूर्त वाक्यविन्यास पेड़ का उपयोग करके कोड बना सकते हैं, फिर इसे compile() पर निष्पादन योग्य कोड में संकलित करने के लिए पास कर सकते हैं। फिर आप कोड चलाने के लिए eval का उपयोग कर सकते हैं।

मुझे यकीन नहीं है कि बाद में उपयोग के लिए संकलित कोड को सहेजने का कोई सुविधाजनक तरीका है (यानी .pyc फ़ाइल में)।

+0

अच्छी तरह से, मैं वास्तव में कुछ मानव-पठनीय चाहता हूँ। निष्पादन योग्य कोड नहीं होना चाहिए। – Jonathanb

+0

पर्याप्त मेला, मैं इस उत्तर को यहां छोड़ दूंगा यदि यह किसी अन्य प्रश्न के लिए किसी अन्य प्रश्न के लिए उपयोगी है। –

0

जो मैं समझता हूं कि आप क्या करने की कोशिश कर रहे हैं, मैं रनटाइम पर कक्षा की गतिशील रूप से जांच करने और उस पर आधारित आउटपुट उत्पन्न करने के प्रतिबिंब का उपयोग करने पर विचार करता हूं। प्रतिबिंब (एके.ए. आत्मनिरीक्षण) पर http://diveintopython3.ep.io/ पर एक अच्छा ट्यूटोरियल है।

आप किसी दिए गए ऑब्जेक्ट के गुणों की सूची प्राप्त करने के लिए dir() फ़ंक्शन का उपयोग कर सकते हैं। किसी ऑब्जेक्ट की दस्तावेज़ स्ट्रिंग __doc__ विशेषता के माध्यम से सुलभ है। यही कारण है, अगर आप एक समारोह या वर्ग आप निम्न कर सकते का डॉक स्ट्रिंग को देखने के लिए चाहते हैं:

>>> def foo(): 
... """A doc string comment.""" 
... pass 
... 
>>> print foo.__doc__ 
A doc string comment. 
+0

मेरे पास जो ग्रह है वह एक समूह है जिसे मैं प्रत्येक को अपनी टेक्स्ट फाइलों के रूप में स्टोर करना चाहता हूं। मैं उन्हें विशेष रूप से पायथन स्रोत कोड के रूप में संग्रहित करने के लिए संलग्न नहीं हूं, लेकिन मैं उन्हें मानव-पठनीय बनाने के लिए जुड़ा हुआ हूं। – Jonathanb

1

मुझे यकीन है कि क्या यह विशेष रूप से pythonic है नहीं कर रहा हूँ, लेकिन आप ऑपरेटर ओवरलोडिंग इस्तेमाल कर सकते हैं:

class CodeGenerator: 
    def __init__(self, indentation='\t'): 
     self.indentation = indentation 
     self.level = 0 
     self.code = '' 

    def indent(self): 
     self.level += 1 

    def dedent(self): 
     if self.level > 0: 
      self.level -= 1 

    def __add__(self, value): 
     temp = CodeGenerator(indentation=self.indentation) 
     temp.level = self.level 
     temp.code = str(self) + ''.join([self.indentation for i in range(0, self.level)]) + str(value) 
     return temp 

    def __str__(self): 
     return str(self.code) 

a = CodeGenerator() 
a += 'for a in range(1, 3):\n' 
a.indent() 
a += 'for b in range(4, 6):\n' 
a.indent() 
a += 'print(a * b)\n' 
a.dedent() 
a += '# pointless comment\n' 
print(a) 

यह निश्चित रूप से आपके उदाहरण से लागू करने के लिए कहीं अधिक महंगा है, और मैं बहुत अधिक मेटा प्रोग्रामिंग से सावधान रहूंगा, लेकिन यह एक मजेदार अभ्यास था।जब आप फिट देखते हैं तो आप इसका विस्तार या उपयोग कर सकते हैं; कैसे के बारे में:

  • एक लिखने विधि जोड़ने और इस का एक उद्देश्य के लिए stdout पुनः निर्देशित एक स्क्रिप्ट फ़ाइल
  • उत्पादन अनुकूलित करने के लिए
  • जोड़ने विशेषता getters और setters
यह से प्राप्ति के लिए सीधे मुद्रित करने के लिए

जो भी आप साथ जाते हैं उसके बारे में सुनना बहुत अच्छा होगा :)

7

बस सर्दियोंम्यूट पर अपनी टिप्पणी पढ़ें - यानी:

मेरे पास जो ग्रह है, वह है, मैं प्रत्येक को अपने स्वयं के टेक्स्ट फ़ाइलों के रूप में स्टोर करना चाहता हूं। मैं विशेष रूप से को पायथन स्रोत कोड, के रूप में संग्रहीत करने के लिए संलग्न नहीं हूं लेकिन मैं उन्हें मानव-पठनीय बनाने के लिए संलग्न हूं।

यदि ऐसा है, तो ऐसा लगता है कि आपको उप-वर्गों की आवश्यकता नहीं है, लेकिन एक ही कक्षा का उपयोग करने और ग्रहों को अकेले डेटा के माध्यम से अलग करने में सक्षम होना चाहिए। और उस स्थिति में, फाइलों को केवल डेटा क्यों न लिखें और जब आपको अपने कार्यक्रम में ग्रह वस्तुओं की आवश्यकता हो, तो वस्तुओं को प्रारंभ करने के लिए डेटा में पढ़ें?

यदि आपको ओवरराइडिंग विधियों जैसी चीजें करने की ज़रूरत है, तो मैं कोड लिखना देख सकता हूं - लेकिन क्या आप अलग-अलग चरों का उपयोग करके सभी ग्रहों के लिए एक ही तरीके से नहीं हो सकते हैं?

डेटा लिखने का लाभ (इसमें पढ़ने योग्यता के लिए लेबल प्रकार की जानकारी शामिल हो सकती है जिसे आप इसे पढ़ते समय छोड़ देंगे) यह है कि गैर-पायथन प्रोग्रामर उन्हें पढ़ने के दौरान विचलित नहीं होंगे, आप इसका उपयोग कर सकते हैं यदि आवश्यक हो तो कुछ अन्य भाषा के साथ एक ही फाइलें, आदि

+1

हाँ, मैं इस बारे में थोड़ा मुश्किल सोच रहा था, मैं नहीं था। यही संभावना है कि मैं क्या करूँगा। धन्यवाद! – Jonathanb

3

मैं कोड उत्पन्न करने के लिए cookiecutter का उपयोग करने की सलाह दूंगा।

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