แยกไฟล์. py อ่าน AST ปรับเปลี่ยนแล้วเขียนรหัสต้นฉบับที่แก้ไขแล้ว


168

ฉันต้องการแก้ไขรหัสต้นฉบับของโปรแกรมแบบหลาม โดยทั่วไปฉันต้องการอ่าน.pyไฟล์สร้างASTแล้วเขียนกลับรหัสต้นฉบับของ Python ที่แก้ไขแล้ว (เช่น.pyไฟล์อื่น)

มีวิธีการที่จะแยก / รหัสที่มาหลามรวบรวมโดยใช้โมดูลหลามมาตรฐานเช่นมีหรือast compilerอย่างไรก็ตามฉันไม่คิดว่าพวกเขาจะสนับสนุนวิธีการแก้ไขซอร์สโค้ด (เช่นลบการประกาศฟังก์ชั่นนี้) แล้วเขียนกลับรหัสต้นฉบับไพ ธ อน

UPDATE: เหตุผลที่ฉันต้องการจะทำคือผมอยากจะเขียนห้องสมุดทดสอบการกลายพันธุ์สำหรับหลามส่วนใหญ่โดยการลบงบ / สำนวน rerunning การทดสอบและเห็นสิ่งที่แบ่ง


4
เลิกใช้แล้วตั้งแต่เวอร์ชัน 2.6: แพ็คเกจคอมไพเลอร์ถูกลบใน Python 3.0 แล้ว
dfa

1
คุณไม่สามารถแก้ไขแหล่งที่มาอะไรได้บ้าง ทำไมคุณไม่เขียนมัณฑนากร?
S.Lott

3
วัวศักดิ์สิทธิ์! ฉันต้องการสร้างเครื่องมือทดสอบการกลายพันธุ์สำหรับงูใหญ่โดยใช้เทคนิคเดียวกัน (โดยเฉพาะการสร้างปลั๊กอินจมูก) คุณวางแผนที่จะเปิดแหล่งที่มาหรือไม่?
ไรอัน

2
@ Ryan Yeah ฉันจะโอเพนซอร์สอะไรก็ได้ที่ฉันสร้าง เราควรให้การติดต่อเกี่ยวกับเรื่องนี้
Rory

1
แน่นอนว่าฉันส่งอีเมลถึงคุณผ่าน Launchpad
Ryan

คำตอบ:


73

Pythoscopeทำสิ่งนี้กับกรณีทดสอบที่สร้างขึ้นโดยอัตโนมัติเช่นเดียวกับเครื่องมือ2to3สำหรับ python 2.6 (มันแปลง python 2.x source เป็น python 3.x source)

เครื่องมือทั้งสองนี้ใช้ไลบรารีlib2to3ซึ่งเป็นการใช้งาน python parser / เครื่องจักรคอมไพเลอร์ที่สามารถเก็บข้อคิดเห็นในแหล่งข้อมูลเมื่อมันถูกปัดเศษจากแหล่ง -> AST -> แหล่ง

โครงการเชือกอาจตอบสนองความต้องการของคุณถ้าคุณต้องการที่จะทำ refactoring มากขึ้นเช่นการแปลง

ASTโมดูลเป็นตัวเลือกอื่น ๆ ของคุณและมีตัวอย่างที่เก่าของวิธีการ "unparse" ต้นไม้ไวยากรณ์กลับเข้ามาในรหัส (โดยใช้โมดูลแจง) แต่astโมดูลมีประโยชน์มากกว่าเมื่อทำการแปลง AST บนโค้ดที่ถูกแปลงเป็นวัตถุรหัส

redbaronโครงการก็อาจจะเป็นแบบที่ดี (HT ซาเวียร์ Combelle)


5
ตัวอย่าง unparse นั้นยังคงอยู่นี่คือรุ่น py3k ที่อัปเดตแล้ว: hg.python.org/cpython/log/tip/Tools/parser/unparse.py
Janus Troelsen

2
เกี่ยวกับunparse.pyสคริปต์ - อาจเป็นเรื่องยุ่งยากที่จะใช้จากสคริปต์อื่น แต่มีเป็นแพคเกจที่เรียกว่า astunparse ( บน GitHub , บน pypi ) unparse.pyซึ่งเป็นพื้นรุ่นบรรจุอย่างถูกต้องของ
mbdevpl

คุณสามารถปรับปรุงคำตอบของคุณโดยเพิ่ม parso เป็นตัวเลือกที่ต้องการได้ไหม มันดีมากและได้รับการปรับปรุง
บรรจุกล่อง

59

โมดูล builtin ast ไม่ได้มีวิธีการแปลงกลับไปยังแหล่งที่มา อย่างไรก็ตามโมดูลcodegenที่นี่ให้เครื่องพิมพ์สวยสำหรับ ast ที่จะช่วยให้คุณทำเช่นนั้น เช่น.

import ast
import codegen

expr="""
def foo():
   print("hello world")
"""
p=ast.parse(expr)

p.body[0].body = [ ast.parse("return 42").body[0] ] # Replace function body with "return 42"

print(codegen.to_source(p))

สิ่งนี้จะพิมพ์:

def foo():
    return 42

โปรดทราบว่าคุณอาจสูญเสียการจัดรูปแบบและความคิดเห็นที่แน่นอนเนื่องจากสิ่งเหล่านี้จะไม่ถูกสงวนไว้

อย่างไรก็ตามคุณอาจไม่จำเป็นต้อง หากสิ่งที่คุณต้องการคือการดำเนินการ AST ที่ถูกแทนที่คุณสามารถทำได้ง่ายๆโดยการเรียกคอมไพล์ () บน ast และดำเนินการวัตถุโค้ดที่เกิดขึ้น


20
สำหรับทุกคนที่ใช้สิ่งนี้ในอนาคต codegen ส่วนใหญ่ล้าสมัยและมีข้อบกพร่องเล็กน้อย ฉันได้แก้ไขสองสามอย่าง ฉันมีสิ่งนี้เป็นส่วนสำคัญใน github: gist.github.com/791312
mattbasta

สังเกตุว่า codegen ล่าสุดนั้นมีการอัพเดทในปี 2012 ซึ่งอยู่หลังความคิดเห็นข้างต้นดังนั้นฉันเดาว่า codegen นั้นได้รับการอัพเดตแล้ว @mattbasta
zjffdu

4
astorดูเหมือนจะเป็นผู้สืบทอดสืบเนื่องจาก codegen
medmunds

20

ในคำตอบที่ต่างออกไปผมแนะนำให้ใช้astorแพ็คเกจ แต่หลังจากนั้นฉันก็พบว่าแพ็คเกจ AST แบบแยกวิเคราะห์ที่ทันสมัยกว่านี้เรียกว่าastunparse:

>>> import ast
>>> import astunparse
>>> print(astunparse.unparse(ast.parse('def foo(x): return 2 * x')))


def foo(x):
    return (2 * x)

ฉันได้ทดสอบสิ่งนี้กับ Python 3.5 แล้ว


19

คุณอาจไม่จำเป็นต้องสร้างซอร์สโค้ดอีกครั้ง แน่นอนว่าเป็นเรื่องอันตรายสำหรับฉันที่จะพูดเนื่องจากคุณไม่ได้อธิบายอย่างแท้จริงว่าทำไมคุณคิดว่าคุณต้องสร้างไฟล์. py เต็มโค้ด แต่:

  • หากคุณต้องการสร้างไฟล์. py ที่ผู้คนจะใช้จริงอาจจะกรอกแบบฟอร์มและรับไฟล์. py ที่มีประโยชน์เพื่อแทรกลงในโครงการของพวกเขาจากนั้นคุณไม่ต้องการเปลี่ยนเป็น AST และ ย้อนกลับเพราะคุณจะสูญเสียการจัดรูปแบบทั้งหมด (ลองนึกถึงบรรทัดว่างที่ทำให้ Python อ่านได้โดยการจัดกลุ่มชุดของบรรทัดที่เกี่ยวข้องเข้าด้วยกัน) ( โหนดแอสต์มีlinenoและcol_offsetแอตทริบิวต์ ) แต่คุณอาจต้องการใช้เครื่องมือสร้างเท็มเพลต ( ภาษาเทมเพลต Djangoเช่นถูกออกแบบมาเพื่อทำให้ไฟล์เทมเพลตแม้แต่ไฟล์ข้อความง่าย) เพื่อปรับแต่งไฟล์. py หรือใช้นามสกุลMetaPythonของ Rick Copeland

  • หากคุณพยายามเปลี่ยนแปลงระหว่างการรวบรวมโมดูลโปรดทราบว่าคุณไม่จำเป็นต้องย้อนกลับไปที่ข้อความ คุณสามารถคอมไพล์ AST โดยตรงแทนที่จะเปลี่ยนเป็นไฟล์. py

  • แต่ในเกือบทุกกรณีคุณอาจพยายามทำบางสิ่งบางอย่างแบบไดนามิกที่ภาษาอย่าง Python ทำให้ง่ายมากโดยไม่ต้องเขียนไฟล์. py ใหม่! หากคุณขยายคำถามของคุณเพื่อแจ้งให้เราทราบว่าคุณต้องการทำอะไรจริง ๆ ไฟล์. py ใหม่อาจไม่เกี่ยวข้องกับคำตอบเลย ฉันได้เห็นโครงการ Python หลายร้อยโครงการที่ทำสิ่งต่าง ๆ ในโลกแห่งความเป็นจริงและไม่ใช่โครงการเดียวที่จำเป็นสำหรับการเขียนไฟล์. py ดังนั้นฉันต้องยอมรับว่าฉันเป็นคนขี้ระแวงที่คุณพบกรณีการใช้งานที่ดีเป็นครั้งแรก :-)

อัปเดต:ตอนนี้คุณได้อธิบายสิ่งที่คุณพยายามจะทำแล้วฉันจะถูกล่อลวงให้ทำงานกับ AST ต่อไป คุณจะต้องกลายพันธุ์โดยการลบไม่ใช่บรรทัดของไฟล์ (ซึ่งอาจส่งผลให้เกิดงบครึ่งที่เพียงแค่ตายด้วย SyntaxError) แต่งบทั้งหมด - และสิ่งที่ดีกว่าที่จะทำเช่นนั้นใน AST?


ภาพรวมที่ดีของวิธีแก้ปัญหาที่เป็นไปได้และทางเลือกอื่น ๆ
Ryan

1
กรณีใช้งานจริงสำหรับการสร้างรหัส: Kid และ Genshi (ฉันเชื่อว่า) สร้าง Python จากเทมเพลต XML สำหรับการเรนเดอร์เพจแบบไดนามิกที่รวดเร็ว
ริกโคปแลนด์

10

การแยกวิเคราะห์และปรับเปลี่ยนโครงสร้างโค้ดเป็นไปได้แน่นอนด้วยความช่วยเหลือของastโมดูลและฉันจะแสดงในตัวอย่างในช่วงเวลา อย่างไรก็ตามการเขียนกลับซอร์สโค้ดที่ปรับเปลี่ยนนั้นไม่สามารถทำได้ด้วยastโมดูลเพียงอย่างเดียว มีโมดูลอื่น ๆ สำหรับงานนี้เช่นหนึ่งที่นี่

หมายเหตุ: ตัวอย่างด้านล่างนี้สามารถใช้เป็นบทช่วยสอนเบื้องต้นเกี่ยวกับการใช้astโมดูลได้ แต่เป็นแนวทางที่ครอบคลุมมากขึ้นเกี่ยวกับการใช้งานastโมดูลสามารถใช้ได้ที่นี่ที่Green Tree งูกวดวิชาและเอกสารอย่างเป็นทางการในastโมดูล

บทนำสู่ ast :

>>> import ast
>>> tree = ast.parse("print 'Hello Python!!'")
>>> exec(compile(tree, filename="<ast>", mode="exec"))
Hello Python!!

คุณสามารถแยกรหัสหลาม (แสดงในสตริง) ast.parse()โดยเพียงแค่การเรียกร้องของ API ส่งกลับหมายเลขอ้างอิงไปยังโครงสร้างต้นไม้บทคัดย่อ (AST) น่าสนใจที่คุณสามารถคอมไพล์กลับโครงสร้างนี้และดำเนินการตามที่แสดงด้านบน

API ที่มีประโยชน์มากอีกตัวหนึ่งคือการast.dump()ทิ้ง AST ทั้งหมดในรูปแบบสตริง มันสามารถใช้ในการตรวจสอบโครงสร้างต้นไม้และมีประโยชน์มากในการแก้ไขข้อบกพร่อง ตัวอย่างเช่น,

บน Python 2.7:

>>> 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:

>>> 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 และ Python 3.5 และความแตกต่างในประเภทของโหนด AST ในแผนผังที่เกี่ยวข้อง


วิธีแก้ไขรหัสโดยใช้ ast :

ทีนี้ลองมาดูตัวอย่างของการดัดแปลงโค้ดไพ ธ อนตามastโมดูล เครื่องมือหลักสำหรับการปรับเปลี่ยนโครงสร้าง AST คือast.NodeTransformerคลาส เมื่อใดก็ตามที่ต้องการแก้ไข AST เขา / เธอต้องการซับคลาสจากมันและเขียนการแปลงโหนดตามนั้น

ตัวอย่างของเราลองเขียนยูทิลิตี้อย่างง่ายที่แปลง Python 2 พิมพ์คำสั่งเป็นการเรียกใช้ฟังก์ชัน Python 3

พิมพ์คำสั่งไปที่ยูทิลิตี้แปลงสาย Fun: 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])

สามารถทดลองใช้งานยูทิลิตี้นี้ในไฟล์ตัวอย่างขนาดเล็กเช่นหนึ่งไฟล์ด้านล่างและควรใช้งานได้ดี

ทดสอบไฟล์อินพุต: 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()

โปรดทราบว่าการเปลี่ยนแปลงดังกล่าวข้างต้นเป็นเพียงสำหรับวัตถุประสงค์การกวดวิชาและในกรณีที่สถานการณ์จริงใครจะต้องมองไปที่สถานการณ์ที่แตกต่างกันทั้งหมดเช่นastprint " x is %s" % ("Hello Python")


6

ฉันได้สร้างเมื่อเร็ว ๆ นี้ค่อนข้างเสถียร (แกนทดสอบอย่างดีจริงๆ) และส่วนขยายของรหัสซึ่งสร้างรหัสจากastต้นไม้: https://github.com/paluh/code-formatter https://github.com/paluh/code-formatter

ฉันใช้โครงการเป็นฐานสำหรับปลั๊กอินขนาดเล็ก (ซึ่งฉันใช้อยู่ทุกวัน) ดังนั้นเป้าหมายของฉันคือการสร้างรหัสไพ ธ อนที่ดีและอ่านได้จริงๆ

PS ฉันพยายามที่จะขยายcodegenแต่สถาปัตยกรรมมันขึ้นอยู่กับast.NodeVisitorอินเตอร์เฟซดังนั้น formatters ( visitor_method) จึงเป็นเพียงฟังก์ชั่น ฉันพบว่าโครงสร้างนี้มีข้อ จำกัด และยากที่จะปรับให้เหมาะสม (ในกรณีที่มีนิพจน์ที่ยาวและซ้อนกันง่ายกว่าที่จะเก็บทรีวัตถุและแคชผลลัพธ์บางส่วน - ในทางอื่นคุณสามารถใช้ความซับซ้อนแทนคุณได้หากต้องการค้นหาเลย์เอาต์ที่ดีที่สุด) แต่ codegenเป็นผลงานของ mitsuhiko ทุกชิ้น (ซึ่งฉันได้อ่าน) นั้นเขียนได้ดีและกระชับ


4

หนึ่งในคำตอบอื่น ๆแนะนำซึ่งดูเหมือนว่าจะได้รับการแทนที่ด้วยเครื่องcodegen astorเวอร์ชั่นของastorPyPI (เวอร์ชั่น 0.5 ในการเขียนนี้) ดูเหมือนว่าจะล้าสมัยเช่นกันดังนั้นคุณสามารถติดตั้งเวอร์ชันการพัฒนาastorดังนี้

pip install git+https://github.com/berkerpeksag/astor.git#egg=astor

จากนั้นคุณสามารถใช้astor.to_sourceในการแปลง Python AST เป็นรหัสแหล่ง Python ที่มนุษย์สามารถอ่านได้:

>>> import ast
>>> import astor
>>> print(astor.to_source(ast.parse('def foo(x): return 2 * x')))
def foo(x):
    return 2 * x

ฉันได้ทดสอบสิ่งนี้กับ Python 3.5 แล้ว


4

หากคุณกำลังดูสิ่งนี้ในปี 2019 คุณสามารถใช้libcstนี้ได้ แพ็คเกจได้ มันมีไวยากรณ์คล้ายกับ ast มันใช้งานได้อย่างมีเสน่ห์และรักษาโครงสร้างของรหัสไว้ มันมีประโยชน์โดยทั่วไปสำหรับโครงการที่คุณต้องเก็บความคิดเห็น, ช่องว่าง, ขึ้นบรรทัดใหม่ ฯลฯ

หากคุณไม่จำเป็นต้องใส่ใจกับความคิดเห็นที่สงวนไว้ช่องว่างและอื่น ๆ การรวมกันของ ast และastor ก็ทำงานได้ดี


2

เรามีความต้องการที่คล้ายกันซึ่งไม่ได้รับการแก้ไขโดยคำตอบอื่น ๆ ที่นี่ ดังนั้นเราจึงสร้างห้องสมุดสำหรับสิ่งนี้ASTTokensซึ่งใช้ต้นไม้ AST ที่สร้างขึ้นด้วยastหรือastroidโมดูลและทำเครื่องหมายด้วยช่วงของข้อความในซอร์สโค้ดต้นฉบับ

มันไม่ได้ทำการแก้ไขโค้ดโดยตรง แต่มันก็ไม่ยากที่จะเพิ่มที่อยู่ด้านบนเนื่องจากมันจะบอกช่วงของข้อความที่คุณต้องแก้ไข

ตัวอย่างเช่นนี่จะเป็นการตัดการเรียกใช้ฟังก์ชันWRAP(...)รักษาความคิดเห็นและทุกสิ่ง:

example = """
def foo(): # Test
  '''My func'''
  log("hello world")  # Print
"""

import ast, asttokens
atok = asttokens.ASTTokens(example, parse=True)

call = next(n for n in ast.walk(atok.tree) if isinstance(n, ast.Call))
start, end = atok.get_text_range(call)
print(atok.text[:start] + ('WRAP(%s)' % atok.text[start:end])  + atok.text[end:])

ผลิต:

def foo(): # Test
  '''My func'''
  WRAP(log("hello world"))  # Print

หวังว่านี่จะช่วยได้!


1

ระบบการเปลี่ยนแปลงโครงการเป็นเครื่องมือที่ข้อความจะแยกวิเคราะห์แหล่งสร้าง asts ช่วยให้คุณสามารถปรับเปลี่ยนได้โดยใช้การเปลี่ยนแปลงแหล่งที่มาต่อแหล่งที่มา ( "ถ้าคุณเห็นรูปแบบนี้แทนที่โดยรูปแบบที่") เครื่องมือดังกล่าวเหมาะอย่างยิ่งสำหรับการกลายพันธุ์ของซอร์สโค้ดที่มีอยู่ซึ่งเป็นเพียง "ถ้าคุณเห็นรูปแบบนี้แทนที่ด้วยรูปแบบตัวแปร"

แน่นอนว่าคุณต้องมีเอ็นจิ้นการแปลงโปรแกรมที่สามารถแยกภาษาที่คุณสนใจและยังคงทำการแปลงรูปแบบ ชุดเครื่องมือการปรับรื้อซอฟต์แวร์ DMSของเราเป็นระบบที่สามารถทำได้และจัดการ Python และภาษาอื่น ๆ ที่หลากหลาย

ดูคำตอบ SOนี้สำหรับตัวอย่างของ AST แบบแยกวิเคราะห์สำหรับ Python ที่จับความคิดเห็นได้อย่างถูกต้อง DMS สามารถทำการเปลี่ยนแปลง AST และสร้างข้อความที่ถูกต้องรวมถึงความคิดเห็น คุณสามารถขอให้พิมพ์สวย AST โดยใช้รูปแบบการจัดรูปแบบของตัวเอง (คุณสามารถเปลี่ยนแปลงเหล่านี้) หรือทำ "การพิมพ์ความจงรักภักดี" ซึ่งใช้ข้อมูลบรรทัดและคอลัมน์ดั้งเดิมเพื่อรักษาเค้าโครงเดิมสูงสุด (การเปลี่ยนแปลงบางส่วนในรูปแบบที่รหัสใหม่ แทรกไม่สามารถหลีกเลี่ยงได้)

ในการใช้กฎ "การกลายพันธุ์" สำหรับ Python ด้วย DMS คุณสามารถเขียนสิ่งต่อไปนี้:

rule mutate_addition(s:sum, p:product):sum->sum =
  " \s + \p " -> " \s - \p"
 if mutate_this_place(s);

กฎนี้แทนที่ "+" ด้วย "-" ในวิธีที่ถูกต้องทางไวยากรณ์; มันทำงานบน AST และดังนั้นจะไม่สัมผัสสตริงหรือความคิดเห็นที่เกิดขึ้นเพื่อดูถูกต้อง เงื่อนไขพิเศษใน "mutate_this_place" คือให้คุณควบคุมความถี่ในการเกิดสิ่งนี้ คุณไม่ต้องการที่จะกลายพันธุ์ทุกที่ในโปรแกรม

เห็นได้ชัดว่าคุณต้องการกฎเพิ่มเติมอีกมากมายเช่นนี้ซึ่งตรวจจับโครงสร้างโค้ดต่างๆและแทนที่ด้วยเวอร์ชันที่กลายพันธุ์ DMS ยินดีที่จะใช้ชุดของกฎ AST ที่กลายพันธุ์นั้นจะถูกพิมพ์ออกมาสวย


ฉันไม่ได้ดูคำตอบนี้ใน 4 ปี ว้าวมันถูกโหวตหลายครั้ง มันน่าทึ่งจริงๆเพราะมันตอบคำถามของ OP โดยตรงและยังแสดงให้เห็นถึงวิธีการกลายพันธุ์ที่เขาต้องการทำ ฉันไม่คิดว่าผู้ลงคะแนนเสียงคนใดจะอธิบายว่าทำไมพวกเขาลงคะแนนเสียง
Ira Baxter

4
เพราะมันส่งเสริมเครื่องมือโอเพนซอร์สที่มีราคาแพงมาก
Zoran Pavlovic

@ ZoranPavlovic: ดังนั้นคุณไม่ได้คัดค้านความถูกต้องทางเทคนิคหรือยูทิลิตี้ใด ๆ ?
Ira Baxter

2
@ โซรัน: เขาไม่ได้บอกว่าเขามีห้องสมุดโอเพ่นซอร์ส เขาบอกว่าเขาต้องการแก้ไขซอร์สโค้ดของ Python (โดยใช้ AST) และวิธีแก้ปัญหาที่เขาพบก็ไม่ได้ทำเช่นนั้น นี่เป็นวิธีแก้ปัญหา คุณไม่คิดว่าคนใช้เครื่องมือเชิงพาณิชย์ในโปรแกรมที่เขียนด้วยภาษาเช่น Python บน Java ใช่ไหม
Ira Baxter

1
ฉันไม่ได้เป็นผู้ลงคะแนน แต่โพสต์อ่านเล็กน้อยเหมือนโฆษณา เพื่อปรับปรุงคำตอบคุณสามารถเปิดเผยได้ว่าคุณมีความเกี่ยวข้องกับผลิตภัณฑ์
wim

0

ฉันเคยใช้บารอนสำหรับสิ่งนี้ แต่ตอนนี้เปลี่ยนไปเป็น parso เพราะมันทันสมัยกับงูใหญ่ที่ทันสมัย มันใช้งานได้ดี

ฉันต้องการสิ่งนี้สำหรับผู้ทดสอบการกลายพันธุ์ มันง่ายมากที่จะสร้างด้วย parso ตรวจสอบรหัสของฉันที่https://github.com/boxed/mutmut

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.