2017-03-11 10 views
6

में टाइप संकेतों को हटाएं मेरे पास पाइथन 3.5 के लिए कुछ स्रोत कोड लिखा गया है जिसे मैं पायथन 3.4 के तहत निष्पादन योग्य बनाना चाहता हूं। 3.5 में से एकमात्र सुविधा जो मैं 3.4 में उपलब्ध नहीं है, संकेत संकेत हैं, इसलिए मैं पूरी तरह से उनको हटाने के लिए एक स्क्रिप्ट लिखना चाहता हूं।पायथन स्रोत प्रोग्रामेटिक

यह पहली नज़र में काफी आसान लग रहा था और मैंने ऐसा करने के लिए कुछ रेगेक्स लिखने का फैसला किया, लेकिन फिर मैंने कुछ किनारे के मामलों के बारे में सोचा और मुझे यकीन नहीं था कि इस तरह के एक जटिल कार्य के लिए समस्या को कैसे हल किया जाए:

def foo(bar: Dict[T, List[T]], 
     baz: Callable[[T], int] = lambda x: (x+3)/7, 
     **kwargs) -> List[T]: 

असल में, मुझे पूरी चीज का विश्लेषण करना होगा और बिना किसी टिप्पणी के तर्क सूची को पुनर्निर्माण करना होगा। मैं इस तक कैसे पहुंचूँगा?

उपयोग पायथन के builtin ast स्रोत कोड पार्स करने के लिए मॉड्यूल डी और फिर उत्कृष्ट astunparse पुस्तकालय फिर से पार्स ast से स्रोत कोड उत्पन्न करने के लिए:

+1

[एएसटी मॉड्यूल] (https://docs.python.org/3/library/ast.html) स्रोत परिवर्तन कार्य में अपने दोस्त, esp है। ['नोडट्रांसफॉर्मर'] (https://docs.python.org/3/library/ast.html#ast.NodeTransformer)। रिवर्स के लिए आपको कुछ तृतीय पक्ष पैकेज की आवश्यकता हो सकती है। –

+0

धन्यवाद। वाह, वह सामान जटिल है ... मैं यह भी नहीं जानता कि इस व्याकरण – Klamann

+1

का उपयोग करके संकेत संकेतों को कैसे पहचानें [व्याकरण] (https://docs.python.org/3/library/ast.html # सार-व्याकरण): उदाहरण के लिए 'Arg' में वैकल्पिक expr 'annotation' और 'FunctionDef' वैकल्पिक expr' रिटर्न' शामिल है। आपका ट्रांसफार्मर उनको हटा देगा। –

उत्तर

6

ठीक है, मैं समझ गया। तब सभी अब सिर्फ़ प्रकार एनोटेशन बाहर निकालना है: एएसटी में

import ast 
import astunparse 

source=""" 
import typing 
from typing import Dict, T, Callable 
from typing import List 

def foo(bar: Dict[T, List[T]], 
     baz: Callable[[T], int] = lambda x: (x+3)/7, 
     **kwargs) -> List[T]: 
    pass 
""" 

class TypeHintRemover(ast.NodeTransformer): 

    def visit_FunctionDef(self, node): 
     # remove the return type defintion 
     node.returns = None 
     # remove all argument annotations 
     if node.args.args: 
      for arg in node.args.args: 
       arg.annotation = None 
     return node 

    def visit_Import(self, node): 
     node.names = [n for n in node.names if n.name != 'typing'] 
     return node if node.names else None 

    def visit_ImportFrom(self, node): 
     return node if node.module != 'typing' else None 

# parse the source code into an AST 
parsed_source = ast.parse(source) 
# remove all type annotations, function return type definitions 
# and import statements from 'typing' 
transformed = TypeHintRemover().visit(parsed_source) 
# convert the AST back to source code 
print(astunparse.unparse(transformed)) 

TypeHintRemover दौरा सभी नोड्स और समारोह तर्क के भीतर सभी प्रकार संकेत निकाल देता है, प्रत्येक कार्य की वापसी प्रकार परिभाषाएं सभी आयात बयान है कि को देखें 'टाइपिंग' मॉड्यूल।

परिणाम है:

def foo(bar, baz=(lambda x: ((x + 3)/7)), **kwargs): 
    pass 
+0

आपका क्या मतलब है? – Klamann

+0

आपको पाइथन 3 में [टाइप संकेत] (https://www.python.org/dev/peps/pep-0484/) के बारे में पढ़ना चाहिए, मैं उन लोगों का एक बड़ा प्रशंसक हूं। जब निष्पादन की बात आती है तो इनपुट और आउटपुट इस उदाहरण के बराबर होते हैं। उदाहरण: 'बार' को एक '' कॉल करने योग्य'] (https://docs.python.org/3/library/typing.html#typing.Callable) माना जाता है, जो कि केवल एक प्रकार का संकेत है, जो ' ', और लैम्बडा उस तर्क का डिफ़ॉल्ट मान नहीं है। प्रकार संकेत पूरी तरह से वैकल्पिक है और रनटाइम के दौरान मूल्यांकन नहीं किया जाएगा। – Klamann

+1

तो कृपया मुझे बताएं कि वास्तव में क्या गुम है, क्योंकि जो कुछ मैं देख सकता हूं, वह सब कुछ जो एक प्रकार का संकेत नहीं है वहां अभी भी है। – Klamann

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