ast
Modül yardımıyla kod yapısının ayrıştırılması ve değiştirilmesi kesinlikle mümkündür ve bir örnekte bir örnekte göstereceğim. Ancak, değiştirilen kaynak kodunu ast
yalnızca modülle yazmak mümkün değildir . Bu iş için burada bulunan gibi başka modüller de var .
NOT: Aşağıdaki örnek, ast
modülün kullanımı ile ilgili giriş niteliğinde bir öğretici olarak ele alınabilir ancak modül kullanımıyla ilgili daha kapsamlı bir kılavuz ast
burada Green Tree yılanları öğreticisinde ve modülle ilgili resmi belgelerde bulunabilirast
.
Giriş ast
:
>>> import ast
>>> tree = ast.parse("print 'Hello Python!!'")
>>> exec(compile(tree, filename="<ast>", mode="exec"))
Hello Python!!
Sadece API'yı çağırarak python kodunu (dizede temsil edilen) ayrıştırabilirsiniz ast.parse()
. Bu, tutamacı Soyut Sözdizimi Ağacı (AST) yapısına döndürür. İlginçtir, bu yapıyı derleyebilir ve yukarıda gösterildiği gibi yürütebilirsiniz.
Bir başka çok faydalı API, ast.dump()
AST'nin tamamını bir dize formunda döker. Ağaç yapısını incelemek için kullanılabilir ve hata ayıklamada çok faydalıdır. Örneğin,
Python 2.7'de:
>>> import ast
>>> tree = ast.parse("print 'Hello Python!!'")
>>> ast.dump(tree)
"Module(body=[Print(dest=None, values=[Str(s='Hello Python!!')], nl=True)])"
Python 3.5'te:
>>> import ast
>>> tree = ast.parse("print ('Hello Python!!')")
>>> ast.dump(tree)
"Module(body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='Hello Python!!')], keywords=[]))])"
Python 2.7 ile Python 3.5 arasındaki baskı ifadesi için sözdizimindeki farka ve ilgili ağaçlardaki AST düğümü tipindeki farka dikkat edin.
Aşağıdakileri kullanarak kod nasıl değiştirilir ast
:
Şimdi, python kodunun ast
modüle göre değiştirilmesine bir örnek verelim . AST yapısını değiştirmek için ana araç ast.NodeTransformer
sınıftır. AST'yi değiştirmek gerektiğinde, alt sınıftan alması ve buna göre Düğüm Dönüşümlerini yazması gerekir.
Örneğimiz için, Python 2, print ifadelerini Python 3 fonksiyon çağrılarına dönüştüren basit bir yardımcı program yazmaya çalışalım.
Fun call dönüştürücü yardımcı programına deyimi yazdır: print2to3.py:
#!/usr/bin/env python
'''
This utility converts the python (2.7) statements to Python 3 alike function calls before running the code.
USAGE:
python print2to3.py <filename>
'''
import ast
import sys
class P2to3(ast.NodeTransformer):
def visit_Print(self, node):
new_node = ast.Expr(value=ast.Call(func=ast.Name(id='print', ctx=ast.Load()),
args=node.values,
keywords=[], starargs=None, kwargs=None))
ast.copy_location(new_node, node)
return new_node
def main(filename=None):
if not filename:
return
with open(filename, 'r') as fp:
data = fp.readlines()
data = ''.join(data)
tree = ast.parse(data)
print "Converting python 2 print statements to Python 3 function calls"
print "-" * 35
P2to3().visit(tree)
ast.fix_missing_locations(tree)
# print ast.dump(tree)
exec(compile(tree, filename="p23", mode="exec"))
if __name__ == '__main__':
if len(sys.argv) <=1:
print ("\nUSAGE:\n\t print2to3.py <filename>")
sys.exit(1)
else:
main(sys.argv[1])
Bu yardımcı program, aşağıdaki gibi küçük bir örnek dosyada denenebilir ve iyi çalışmalıdır.
Test Giriş dosyası: py2.py
class A(object):
def __init__(self):
pass
def good():
print "I am good"
main = good
if __name__ == '__main__':
print "I am in main"
main()
Yukarıdaki dönüşümün yalnızca ast
eğitim amaçlı olduğunu ve gerçek durumda senaryo gibi tüm farklı senaryolara bakılması gerektiğini lütfen unutmayın print " x is %s" % ("Hello Python")
.