Cách tạo chương trình dòng lệnh bằng Python với Click

Click là một gói Python để viết các giao diện dòng lệnh với ít code nhất có thể. Bài viết này sẽ hướng dẫn các bạn cách sử dụng Click để tạo chương trình dòng lệnh.

Viết chương trình dòng lệnh không cần Click

Bạn có thể viết các chương trình dòng lệnh mà không cần đến Click nhưng yêu cầu nhiều kỹ năng và code hơn. Bạn cần phân tích cú pháp lệnh, thực hiện xác thực, phát triển logic để xử lý các tham số khác nhau và xây dựng một menu trợ giúp tùy chỉnh. Nếu muốn thêm tùy chọn mới, bạn cần sửa đổi chức năng trợ giúp.

Sẽ rất hữu ích khi bạn có thể tự viết code của riêng mình, đây là cách tuyệt vời để học ngôn ngữ lập trình Python, nhưng Click cho phép bạn tuân theo nguyên tắc “Don’t Repeat Yourself” (Đừng lặp lại những gì giống nhau - DRY). Nếu không sử dụng Click, bạn sẽ phải tự viết code và bảo trì bất cứ khi nào có thay đổi.

Đây là một giao diện dòng lệnh đơn giản được code mà không cần Click:

import sys
import random

def do_work():
""" Function to handle command line usage"""
args = sys.argv
args = args[1:] # First element of args is the file name

if len(args) == 0:
print('You have not passed any commands in!')
else:
for a in args:
if a == '--help':
print('Basic command line program')
print('Options:')
print(' --help -> show this basic help menu.')
print(' --monty -> show a Monty Python quote.')
print(' --veg -> show a random vegetable')
elif a == '--monty':
print('What\'s this, then? "Romanes eunt domus"? People called Romanes, they go, the house?')
elif a == '--veg':
print(random.choice(['Carrot', 'Potato', 'Turnip']))
else:
print('Unrecognised argument.')

if __name__ == '__main__':
do_work()

Code không cần Click

27 dòng Python này hoạt động tốt nhưng rất dễ vỡ. Khi thực hiện bất cứ thay đổi nào trên chương trình, bạn cũng cần thay đổi các code hỗ trợ khác. Nếu thay đổi tên một tham số, bạn cần phải cập nhật thông tin trợ giúp và thường hay bị nhầm lẫn.

Đây là logic tương tự nhưng sử dụng với Click:

import click
import random
@click.command()
@click.option('--monty', default=False, help='Show a Monty Python quote.')
@click.option('--veg', default=False, help='Show a random vegetable.')
def do_work(monty, veg):
""" Basic Click example will follow your commands"""
if monty:
print('What\'s this, then? "Romanes eunt domus"? People called Romanes, they go, the house?')
if veg:
print(random.choice(['Carrot', 'Potato', 'Turnip']))
if __name__ == '__main__':
do_work()

Bạn có thể thấy Click thực hiện cùng một logic nhưng chỉ với 16 dòng code thay vì 27 dòng code như trên. Và bạn không cần phân tích tham số và nó sẽ tự tạo màn hình trợ giúp.

Viết code với Click

Đây chỉ là ví dụ so sánh cơ bản để có thể thấy việc sử dụng các chương trình như Click sẽ giúp bạn tiết kiệm nhiều công sức và thời gian. Mặc dù giao diện dòng lệnh đến tay người dùng cuối là như nhau nhưng code tạo nên chương trình đó thì đơn giản hơn, giúp bạn tiết kiệm được nhiều thời gian viết code.

Làm quen với Click trong Python

Trước khi sử dụng Click, bạn có thể cấu hình một môi trường ảo. Điều này sẽ ngăn chặn các gói Python xung đột với hệ thống Python hoặc các dự án khác mà bạn đang làm việc. Bạn có thể thử Python trong trình duyệt nếu muốn tìm hiểu thêm Python và Click.

Cuối cùng, đảm bảo bạn đang chạy Python phiên bản 3. Mặc dù có thể sử dụng Click với Python phiên bản 2 nhưng những ví dụ ở đây là trong Python 3.

Cài đặt Click từ dòng lệnh sử dụng PIP.

pip install click

Viết chương trình Click đầu tiên

Trong trình soạn thảo văn bản, hãy bắt đầu bằng cách nhập Click:

import click

Sau khi nhập Click, tạo một method và điểm nhập main.

import click
import random

def veg():
""" Basic method will return a random vegetable"""
print(random.choice(['Carrot', 'Potato', 'Turnip', 'Parsnip']))

if __name__ == '__main__':
veg()

Script đơn giản này sẽ xuất một loại rau ngẫu nhiên. Code của bạn có thể khác nhưng ví dụ đơn giản này là cách hoàn hảo để kết nối với Click.

Lưu nó thành click_example.py và sau đó chạy nó trong dòng lệnh (sau khi điều hướng đến vị trí của nó):

>python click_example.py

Bạn sẽ thấy tên rau ngẫu nhiên, bây giờ hãy cải thiện code này bằng cách thêm Click. Thay đổi code của bạn để chứa các decorator và vòng lặp for trong Python:

@click.command()
@click.option('--total', default=3, help='Number of vegetables to output.')
def veg(total):
""" Basic method will return a random vegetable"""
for number in range(total):
print(random.choice(['Carrot', 'Potato', 'Turnip', 'Parsnip']))

if __name__ == '__main__':
veg()

Khi chạy, bạn sẽ thấy một loại rau ngẫu nhiên được hiển thị ba lần. Hãy cùng phân tích code trên nhé.

Decorator @click.command() cấu hình Click để làm việc với hàm Python ngay sau decorator. Trong trường hợp này, đây là hàm veg(). Bạn cần nó cho các phương thức sử dụng cùng với Click.

Decorator @click.option cấu hình Click để chấp nhận tham số từ dòng lệnh, chuyển đến phương thức của bạn. Có ba tham số được sử dụng ở đây:

  • –total: Đây là tên dòng lệnh cho tham số total.
  • default: Nếu không xác định tổng tham số khi sử dụng với script, Click sẽ sử dụng giá trị mặc định.
  • help: Đây là câu ngắn gọn giải thích cách sử dụng chương trình.

Hãy xem ví dụ thực tế sử dụng Click. Từ dòng lệnh, chạy script nhưng pass tham số total như sau:

python click_example.py --total 10

Khi thiết lập –total 10 từ dòng lệnh, script sẽ in 10 loại rau ngẫu nhiên. Nếu sử dụng cờ -help, bạn sẽ thấy một trang trợ giúp cùng với các tùy chọn bạn có thể sử dụng:

python click_example.py --help

Trang trợ giúp

Thêm lệnh khác

Bạn có thể sử dụng nhiều decorator Click trên cùng một hàm. Thêm tùy chọn Click khác vào hàm veg như sau:

@click.option('--gravy', default=False, help='Append "with gravy" to the vegetables.')

Tuy nhiên, đừng quên truyền nó vào trong phương thức:

def veg(total, gravy):

Bây giờ khi chạy file, bạn có thể truyền trong cờ gravy:

python click_example.py --gravy y

Màn hình trợ giúp cũng thay đổi:

Màn hình trợ giúp thay đổi

Đây là toàn bộ code (với một số thay đổi code nhỏ để trông gọn gàng hơn):

import click
import random

@click.command()
@click.option('--gravy', default=False, help='Append "with gravy" to the vegetables.')
@click.option('--total', default=3, help='Number of vegetables to output.')
def veg(total, gravy):
""" Basic method will return a random vegetable"""
for number in range(total):
choice = random.choice(['Carrot', 'Potato', 'Turnip', 'Parsnip'])

if gravy:
print(f'{choice} with gravy')
else:
print(choice)

if __name__ == '__main__':
veg()

Các tùy chọn Click khác

Khi đã biết những điều cơ bản về Click bạn có thể bắt đầu xem xét các tùy chọn Click phức tạp hơn. Trong ví dụ này, bạn sẽ học cách truyền một vài giá trị vào một tham số để Click chuyển đổi thành kiểu dữ liệu tuple.

Tạo một file mới có tên là click_example_2.py. Đây là code bạn cần:

import click
import random

@click.command()
def add():
""" Basic method will add two numbers together."""
pass

if __name__ == '__main__':
add()

Sau đó, thêm @click.option được gọi là numbers:

@click.option('--numbers'>, nargs=2, type=int, help='Add two numbers together.')

Code mới duy nhất ở đây là nargs=2, và tùy chọn type=int để Click chấp nhận hai giá trị cho tùy chọn numbers và cả hai giá trị này phải là số nguyên. Bạn có thể thay đổi thành bất cứ số hoặc kiểu giá trị (hợp lệ) nào bạn thích.

Cuối cùng, thay đổi phương thức add để chấp nhận tham số numbers và thực hiện một số thay đổi với chúng:

def add(numbers):
""" Basic method will add two numbers together."""
result = numbers[0] + numbers[1]
print(f'{numbers[0]} + {numbers[1]} = {result}')

Mỗi giá trị bạn pass đều có thể truy cập thông qua đối tượng numbers. Đây là cách sử dụng nó trong dòng lệnh:

python click_example_2.py --numbers 1 2

Các tùy chọn Click khác

Chúc các bạn thực hiện thành công!

Xem thêm:

Thứ Hai, 08/10/2018 15:29
51 👨 2.870
0 Bình luận
Sắp xếp theo