Phân tích cú pháp và sửa đổi cấu trúc mã chắc chắn có thể thực hiện được với sự trợ giúp của mô-đun
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4 và tôi sẽ trình bày nó trong một ví dụ trong giây lát. Tuy nhiên, không thể ghi lại mã nguồn đã sửa đổi chỉ với mô-đun >>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4. Có các mô-đun khác có sẵn cho công việc này, chẳng hạn như một ở đâyGHI CHÚ. Ví dụ dưới đây có thể được coi là hướng dẫn giới thiệu về cách sử dụng mô-đun
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4 nhưng hướng dẫn toàn diện hơn về cách sử dụng mô-đun >>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4 có tại đây tại Hướng dẫn về rắn cây xanh và tài liệu chính thức về mô-đun >>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4Giới thiệu về
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> exec[compile[tree, filename="", mode="exec"]]
Hello Python!!
Bạn có thể phân tích cú pháp mã python [được biểu thị bằng chuỗi] bằng cách gọi API
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
1. Điều này trả về tay cầm cho cấu trúc Cây cú pháp trừu tượng [AST]. Điều thú vị là bạn có thể biên dịch lại cấu trúc này và thực thi nó như hình trênMột API rất hữu ích khác là
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
2 kết xuất toàn bộ AST ở dạng chuỗi. Nó có thể được sử dụng để kiểm tra cấu trúc cây và rất hữu ích trong việc gỡ lỗi. Ví dụ,Trên 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]]]"
Trên 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=[]]]]]"
Lưu ý sự khác biệt về cú pháp cho câu lệnh in trong Python 2. 7 so với. Trăn 3. 5 và sự khác biệt về loại nút AST trong các cây tương ứng
Cách sửa đổi mã bằng cách sử dụng
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4Bây giờ, hãy xem một ví dụ về sửa đổi mã python bằng mô-đun
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4. Công cụ chính để sửa đổi cấu trúc AST là lớp >>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
5. Bất cứ khi nào một người cần sửa đổi AST, anh ấy/cô ấy cần phân lớp từ nó và viết [các] Chuyển đổi nút tương ứngVí dụ của chúng ta, hãy thử viết một tiện ích đơn giản để chuyển đổi các câu lệnh in của Python 2 thành lệnh gọi hàm của Python 3
In sao kê sang tiện ích chuyển đổi cuộc gọi Fun. in2to3. 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
'''
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] >> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
4 và trong tình huống thực tế, người ta sẽ phải xem xét tất cả các tình huống khác nhau, chẳng hạn như >>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
7AST là viết tắt của Abstract Syntax Tree, là một công cụ mạnh mẽ của ngôn ngữ lập trình Python. Nó cho phép chúng ta tương tác với chính mã Python và có thể sửa đổi nó
Bạn đã bao giờ nghĩ về cách mã Python được chạy chưa?
Dành cho những ai chưa biết, trình thông dịch Python chịu trách nhiệm chạy mã Python. Nó tuân theo các hướng dẫn được viết sẵn để dịch mã Python thành các hướng dẫn mà máy có thể chạy
Sau đây là quá trình chuyển đổi mã Python thành mã máy
- Khi chúng tôi chạy mã, mã được phân tích cú pháp thành các phần nhỏ hơn được gọi là mã thông báo. Các mã thông báo này được tạo theo các hướng dẫn được xác định trước sẽ xử lý khác nhau. Ví dụ: từ khóa khác là một từ khóa khác với giá trị số như
- Các mã thông báo được lưu trữ trong danh sách được chuyển đổi để xây dựng cây Cú pháp trừu tượng, AST. AST là tập hợp của hai hoặc nhiều nút được liên kết với nhau dựa trên ngữ pháp của ngôn ngữ Python
- Trình biên dịch có thể tạo ra lệnh cấp thấp hơn được gọi là mã nhị phân từ AST. Code này rất chung chung để máy tính dễ chạy
- Khi trình thông dịch nhận được mã byte giống như hướng dẫn, trình thông dịch hiện có thể chạy mã. Mã byte chịu trách nhiệm gọi hàm trong hệ điều hành, cuối cùng sẽ tương tác với CPU và bộ nhớ để chạy chương trình
Mô tả ở trên là một bản phác thảo sơ bộ về cách trình thông dịch chạy mã Python bằng AST
Chế độ biên dịch mã
Có ba chế độ có sẵn để biên dịch mã. Chúng được đưa ra dưới đây
- exec - Chế độ này được sử dụng để thực thi mã Python bình thường
- eval - Chế độ này được sử dụng để đánh giá biểu thức của Python và sẽ trả về kết quả sau khi đánh giá
- single - Chế độ này hoạt động như trình bao Python thực thi một câu lệnh tại một thời điểm
Thực thi mã Python
Sử dụng mô-đun AST, chúng ta có thể chạy mã Python. Hãy hiểu ví dụ sau
Ví dụ -
đầu ra
Hello Learner! Welcome to JavaTpoint
Đánh giá biểu thức Python
Mô-đun AST cho phép chúng tôi đánh giá biểu thức Python và trả về kết quả từ biểu thức. Hãy hiểu ví dụ sau
Ví dụ -
đầu ra
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
0Tạo AST nhiều dòng
Trong ví dụ trước, chúng ta đã thấy AST dòng đơn và cách kết xuất chúng. Bây giờ, chúng ta sẽ tìm hiểu cách tạo AST nhiều dòng. Đầu tiên, hãy hiểu ví dụ sau
Ví dụ -
đầu ra
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
1NodeTransformer và NodeVisitor
Lớp NodeTransformer được sử dụng để lấy các loại khác nhau và sửa đổi theo yêu cầu của chúng tôi. Module ast cũng cung cấp lớp NodeVisitor giúp chúng ta gọi hàm visit mỗi khi lướt qua cây. Để chúng ta có thể kiểm soát nhiều hơn trên các nút, hãy hiểu ví dụ sau
Ví dụ 1
đầu ra
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
2Giải trình -
Trong đoạn mã trên, chúng tôi đã nhập mô-đun ast để phân tích mã. Sau đó, chúng tôi đã xác định lớp Khách truy cập kế thừa lớp NodeVisitor. Mỗi khi tìm thấy nút chuỗi;
Chúng ta cũng có thể sử dụng module khi chạy trực tiếp mã nguồn. Hãy hiểu ví dụ sau
Ví dụ - 2
đầu ra
>>> import ast
>>> tree = ast.parse["print 'Hello Python!!'"]
>>> ast.dump[tree]
"Module[body=[Print[dest=None, values=[Str[s='Hello Python!!']], nl=True]]]"
3Giải trình -
Đoạn mã trên chuyển đổi tệp Python thành cây cú pháp trừu tượng. Sau đó, chúng tôi phân tích cây để có được thông tin hữu ích
Chúng tôi đã mở tệp Python ở chế độ đọc và sau đó tạo AST có tên là ast_tree. Sau đó, hàm parse[] đã xử lý tất cả các mã thông báo, tuân theo tất cả các quy tắc ngôn ngữ và xây dựng cấu trúc dữ liệu dạng cây bao gồm nhiều thông tin hữu ích
Cây không là gì ngoài một tập hợp các nút, trong đó một biến cây được tham chiếu đến nút "gốc". Như vậy, chúng ta có thể thăm từng nút trong cây và thực hiện các thao tác. Nhưng, trước tiên, chúng tôi truy cập từng nút và xử lý dữ liệu
Phân tích AST
Khi chúng tôi có được cây, bây giờ Trình phân tích sẽ tuân theo mẫu khách truy cập. Sử dụng lớp NodeVisitor, chúng ta có thể theo dõi bất kỳ nút nào trong Python. Chúng ta cần triển khai một phương thức visit_để truy cập một loại nút cụ thể. Trong ví dụ trước, chúng tôi đã sử dụng tập lệnh bên dưới
Ví dụ -
Mã chấp nhận tên của mô-đun và lưu trữ nó trong danh sách thống kê. Với sự trợ giúp của lớp NodeVisitor, chúng ta có thể phân tích cây
Phương thức visit[] sẽ hoạt động giống như phương thức visit_method
Sử dụng AST làm Công cụ phân tích
Sau khi mã Python biến thành mã byte, con người không thể đọc được. Nhưng nó làm cho trình thông dịch nhanh, có nghĩa là mã byte được thiết kế cho máy chứ không phải cho con người
AST bao gồm đủ thông tin có cấu trúc, giúp chúng hữu ích trong việc tìm hiểu về mã Python. Tuy nhiên, AST vẫn không thân thiện với người dùng, nhưng chúng dễ hiểu hơn nhiều so với biểu diễn mã byte
Khi nào sử dụng mô-đun Python AST?
Cây cú pháp trừu tượng khá hữu ích cho các công cụ bảo hiểm mã. Nó phân tích cú pháp mã nguồn và tìm ra các lỗi và sai sót có thể có trong mã. Nó cũng có thể sử dụng trong -
- Nó được sử dụng như một trình thông dịch Python tùy chỉnh
- Nó được sử dụng để phân tích mã tĩnh
- Nó làm cho các IDE trở nên thông minh, được gọi là IntelliSense
Phần kết luận
Chúng ta đã tìm hiểu về mô-đun ast trong Python, mô-đun chịu trách nhiệm chạy mã Python. Sau đó, chúng tôi đã xây dựng cây AST từ mã Python và thực hiện phân tích trên AST bằng lớp NodeVisitor