mypy – Fullstack Station https://fullstackstation.com Hướng dẫn lập trình, thiết kế, lập trình web, thiết kế web, lập trình javascript, lập trình fullstack từ cơ bản đến nâng cao Wed, 24 Apr 2024 08:24:44 +0000 vi hourly 1 https://wordpress.org/?v=6.8.3 https://fullstackstation.com/wp-content/uploads/2019/08/favicon.ico mypy – Fullstack Station https://fullstackstation.com 32 32 Python: Sự cần thiết của MyPy https://fullstackstation.com/gioi-thieu-mypy-python/ https://fullstackstation.com/gioi-thieu-mypy-python/#respond Wed, 24 Apr 2024 08:24:43 +0000 https://fullstackstation.com/?p=1948 Nhân việc người tạo ra Python, ông Guido van Rossum giới thiệu về MyPy, mình sẽ nói kỹ thêm về sự hữu dụng và sự cần thiết của MyPy trong lập trình Python. Bạn có thể tải về slide của ông Guido van Rossum ở cuối bài. Mình đã giới thiệu MyPy trong bài viết […]

The post Python: Sự cần thiết của MyPy appeared first on Fullstack Station.

]]>
Nhân việc người tạo ra Python, ông Guido van Rossum giới thiệu về MyPy, mình sẽ nói kỹ thêm về sự hữu dụng và sự cần thiết của MyPy trong lập trình Python. Bạn có thể tải về slide của ông Guido van Rossum ở cuối bài.

Mình đã giới thiệu MyPy trong bài viết “Giới thiệu một số công cụ hỗ trợ lập trình Python“, bài này sẽ đề cập chi tiết hơn về MyPy. Bất kỳ ngôn ngữ nào cũng phải trải qua quá trình dài để phát triển. Việc thiếu một vài tính năng ngay từ đầu cũng không có gì lạ, vì nguyên tắc thiết kế của Python là đặt sự đơn giản lên hàng đầu.

The Zen of Python (import this):

  • Beautiful is better than ugly.
  • Explicit is better than implicit.
  • Simple is better than complex.
  • Complex is better than complicated.
  • Flat is better than nested.
  • Sparse is better than dense.
  • Readability counts.
  • Special cases aren’t special enough to break the rules.
  • Although practicality beats purity.
  • Errors should never pass silently.
  • Unless explicitly silenced.
  • In the face of ambiguity, refuse the temptation to guess.
  • There should be one– and preferably only one –obvious way to do it.
  • Although that way may not be obvious at first unless you’re Dutch.
  • Now is better than never.
  • Although never is often better than right now.
  • If the implementation is hard to explain, it’s a bad idea.
  • If the implementation is easy to explain, it may be a good idea.
  • Namespaces are one honking great idea — let’s do more of those!

Tuy nhiên, sự cần thiết của kiểm tra kiểu dữ liệu là rất quan trọng, dù nó đã không được hỗ trợ ngay từ lúc ban đầu. Hoặc cũng không là bắt buộc ở hiện tại. Không biết ông Guido hối hận gì không vì đã không đưa type-checking vào Python trước đây :D.

MyPy là gì

Ngày nay, nhiều công cụ để kiểm tra kiểu dữ liệu, nhưng MyPy trước đây được tạo ra bởi anh JukkaL, thì bây giờ đã được đưa chính thức vào chung với Python: https://github.com/python/mypy. Đó là một sự thừa nhận sự phát triển và trưởng thành của MyPy.

Type Annotation

Type checking (kiểm tra kiểu dữ liệu) là xác định rõ kiểu dữ liệu của biến, giúp phát hiện lỗi sớm hơn trong quá trình phát triển. MyPy là công cụ được sử dụng để kiểm tra các lỗi liên quan đến loại dữ liệu dựa trên type annotations.

Ví dụ:

def add(x, y):    
    return x + y

add("hai", "ba")
=> "haiba" # Kiểu string
add(2, 3)
=> 5 # Kiểu integer

add("hai", 3)
hoặc 
add(2, "ba")
=> chúng ta sẽ bị lỗi `TypeError` lúc Runtime

Vậy thì với cách viết thêm kiểu dữ liệu như dưới đây:

def add(x: int, y: int) -> int:    
    return x + y

Khi dùng MyPy để kiểm tra, thì chúng ta sẽ phát hiện ngay được lỗi trong lúc lập trình mà không sợ sẽ bị lỗi lúc runtime nữa. Python khá dễ viết nếu mã nguồn đơn giản, ngắn gọn và còn mới. Nhưng khi mã nguồn dự án trải qua thời gian dài, và lượng code phình to ra thì nếu không có xác định, kiểm tra loại dữ liệu thì sẽ gặp rất nhiều khó khăn khi debug hoặc khó hiểu khi đọc code.

Type T

Sử dụng với các kiểu dữ liệu

Kiểu dữ liệu cơ bản

Bạn có thể dùng tất cả các kiểu dữ liệu cơ bản để diễn giải kiểu dữ liệu như int, float, str, dict, tuple, set, list…, hoặc kết hợp như Tuple[int, str], Iterator[int]…

def gcd(a: int, b: int) -> int:
    while a:
        a, b = b % a, a
    return b

Ở đây mình dùng VSCode, đưa trỏ chuột vào b sẽ biết b có kiểu dữ liệu gì

Hay với ví dụ của trang chủ mypy:

from typing import Iterator

def fib(n: int) -> Iterator[int]:
    a, b = 0, 1
    while a < n:
        yield a
        a, b = b, a + b

Loại biến gọi hàm (Callable)

from typing import Callable

def twice(i: int, next: Callable[[int], int]) -> int:    
    return next(next(i))

def add(i: int) -> int:
    return i + 1

print(twice(3, add))  # 5

Với ví dụ trên, bạn có thể xác định biến đưa vào có thể gọi hàm, rất tường minh.

Kiểu dữ liệu nâng cao

Sử dụng MyPy tuy dễ nhưng cũng cần thời gian để thành thạo, bạn có thể cải thiện Type-Annotation từng bước nhỏ một. Không nhất thiết phải làm 1 lúc cho toàn bộ mã nguồn của dự án. Như vậy sẽ không bị ngán và lười.

Tuy nhiên với dự án mới thì hãy sử dụng Type-Annotation càng nhiều càng tốt. Vừa lập trình vừa có trợ lý MyPy thật là sướng biết bao.

https://mypy.readthedocs.io/en/latest/

MyPy cho Django: https://github.com/machinalis/mypy-django

The post Python: Sự cần thiết của MyPy appeared first on Fullstack Station.

]]>
https://fullstackstation.com/gioi-thieu-mypy-python/feed/ 0
Giới thiệu một số công cụ hỗ trợ lập trình Python https://fullstackstation.com/gioi-thieu-mot-so-cong-cu-ho-tro-lap-trinh-python/ https://fullstackstation.com/gioi-thieu-mot-so-cong-cu-ho-tro-lap-trinh-python/#comments Thu, 21 Mar 2019 15:53:49 +0000 http://fullstackstation.com/?p=1484 Như bất kỳ các ngôn ngữ khác, mình luôn quan trọng các công cụ hỗ trợ để lập trình tốt hơn, nên khi học và sử dụng python mình cũng tìm hiểu các công cụ hỗ trợ, nhận thấy sự hiệu quả đó mình tổng hợp và chia sẽ với các bạn ở bài viết […]

The post Giới thiệu một số công cụ hỗ trợ lập trình Python appeared first on Fullstack Station.

]]>
Như bất kỳ các ngôn ngữ khác, mình luôn quan trọng các công cụ hỗ trợ để lập trình tốt hơn, nên khi học và sử dụng python mình cũng tìm hiểu các công cụ hỗ trợ, nhận thấy sự hiệu quả đó mình tổng hợp và chia sẽ với các bạn ở bài viết này các công cụ đó.

Các công cụ hỗ trợ kiểm tra kiểu dữ liệu

Kiểm tra kiểu dữ liệu là gì?

Đối với các ngôn ngữ lập trình kiểu động, thông dịch như Python, Javascript (Xem thêm Flow: type-checker cho Javascript), Php thì kiểu dữ liệu không bị ràng buộc dẫn đến việc 1 biến, 1 hàm có thể nắm giữ/trả về các kiểu dữ liệu khác nhau trong quá trình thực thi. Mặc dù đây là đặc tính của những ngôn ngữ này, chứ không hẳn là 1 điểm yếu, tuy nhiên để nâng cao khả năng hạn chế lỗi thì chúng ta vẫn cần nâng cao khả năng viết code và sự hỗ trợ của các công cụ.

Ví dụ:

def add(x, y):    
    return x + y

add("hai", "ba")
=> "haiba" # Kiểu string
add(2, 3)
=> 5 # Kiểu integer

add("hai", 3)
hoặc 
add(2, "ba")
=> chúng ta sẽ bị lỗi `TypeError`

Điều này thường dẫn đến các lỗi chương trình mà có xác suất xảy ra thấp và chỉ phát hiện trong lúc thực thi, khiến cho việc gỡ lỗi rất khó khăn.Tầm quan trọng của việc kiểm tra kiểu dữ liệu (type checker) khá cao, và cũng được nói rõ PEP 484 (https://www.python.org/dev/peps/pep-0484/), dựa vào PEP 484 ta sẽ sửa lại như sau:

def add(x: int, y: int) -> int:    
    return x + y

Như vậy, mã nguồn có tính dễ đọc dễ hiểu ngay đầu vào và kết quả trả về của hàm, mã nguồn có tính dễ bảo trì và sẽ hạn chế lỗi không mong muốn. Trong mã nguồn chỉ cần bạn viết theo cấu trúc đó là bạn đã hoàn thành nhiệm vụ của bạn, phần còn lại hãy để các công cụ hỗ trợ bạn.

Ưu và khuyết điểm

Ưu điểm:

  • Nâng cao khả năng hạn chế lỗi lúc thực thi vì có thể phát hiện được lỗi trong quá trình lập trình.
  • Nâng cao khả năng dễ đọc của mã nguồn vì tính rõ ràng của dữ liệu, giúp các lập trình viên dễ dàng nắm rõ chương trình hơn.
  • Khả năng hiểu cấu trúc của chương trình tốt hơn khi bạn nắm vững luồng dữ liệu lúc thực thi.

Khuyết điểm:

  • Giống như hướng tiếp cận TDD (Test-driven development) thì việc viết code theo hướng có chú giải sẽ mất nhiều thời gian hơn 1 chút, và code nặng hơn 1 tí.
  • Mặc dù có type-checker nhưng bản chất Python là dynamic typed, vì vậy kiểu dữ liệu vẫn được tự do bất chấp bạn có viết diễn giải (annotation) kiểu dữ liệu.
  • Cần sử dụng cách viết trong toàn bộ mã nguồn để đạt hiệu quả. Giả sử hàm trên addđược gọi từ 1 hàm khác, và dữ liệu truyền vào không xác định được, thì các công cụ type-checker cũng không kiểm tra được.

Static typing. Sure “real” developers may not need static typing, but if you end up in a situation where a system needs a critical bug fix and the core developers aren’t around anymore or on vacation, and the fix needs to roll out to millions of users, any static analysis ahead of runtime is extremely useful.

Wolfgang Grieskamp, Google Inc.
Tạm dịch: Rõ ràng là đối với lập trình viên thực thụ sẽ không cần quan tâm kiểu dữ liệu, nhưng một lúc nào đó bạn đối mặt với hoàn cảnh là hệ thống cần sửa lỗi nghiêm trọng, và lập trình viên chính không ở đó hoặc đang trong kỳ nghỉ, và việc sửa lỗi ảnh hưởng đến hàng triệu người dùng, thì việc phân tích kiểu dữ liệu trước khi thực thi là cực kỳ cần thiết.

Pyre và Mypy, Pyright

Pyre: https://pyre-check.org/

Mypy: http://mypy-lang.org

Mypy là công cụ được tạo ra trước, nhưng Pyre do Facebook tạo ra, và do cũng được kỳ vọng do đã thành công với các ngôn ngữ khác như Flow cho Javascript hay Hack cho PHP nên Pyre có thể được ưu chuộng hơn. Cá nhân mình sử dụng Mypy là chính, nhưng cũng có cài thêm Pyre để sử dụng cả 2 thì cũng không ảnh hưởng gì. Mặc dù Pyre được quảng cáo là chạy nhanh, nhưng do tính chất chạy nền của các loại công cụ này nên việc nhanh hơn thực sự không quan trọng lắm.

Pyright: https://github.com/Microsoft/pyright

Microsoft đã gia nhập cuộc chơi static type-checker cho Python bằng Pyright, với sự quảng cáo là tốc độ nhanh hơn gấp 5 lần mypy, đây là một ngôi sao mới cần được trải nghiệm. Điểm đặc biệt nữa của Pyright là dùng Typescript nên không phụ thuộc vào môi trường Python.

Pytype

Mặc dù Pytype cũng là 1 công cụ type-checker nhưng với khả năng kiểm tra kiểu dữ liệu không cần type-annotations nghĩa là bạn không cần phải viết chú thích (tuy nhiên đó không phải là mục tiêu của Pytype), đồng thời có thể kiểm tra nhiều kiểu lỗi khác.

Điểm đặc biệt của Pytype là có thể cải tạo các mã nguồn không có type-annotations thành có, tuy nhiên hiện tại chỉ mới dừng ở mức độ từng file, nên nếu dự án có lượng mã nguồn lớn thì cũng tốn nhiều công sức chuyển đổi.

Pycharm

Bạn đang dùng Pycharm thì chúc mừng bạn là type-checker đã được hỗ trợ tích hợp sẵn công cụ type-checker. Tuy nhiên, mình không dùng Pycharm vì phải trả phí cho bản Pro (bản Community khá hạn chế) trong khi hiện tại mình dùng VSCode khá tốt.

Các công cụ hỗ trợ format code

Nếu bạn dùng Pycharm, bạn có thể không cần suy nghĩ nhiều về format code, nhưng trong khía cạnh này có rất nhiều công cụ: autopep8, yapf của Google, Black, isort

Mình thì sử dụng Black, xài rất tốt và hiện tại cũng đạt hơn 8500 stars ở Github gần bằng Yapf, mặc dù được phát triển sau này nhưng Black cũng đạt được tiếng vang tốt, mình nghĩ dùng Black là ổn.

Các công cụ về Linting

Linting thì đa phần các IDE, hay các Text Editors có hỗ trợ Python thì đều có cài đặt sẵn các công cụ lint như Pyflakes, Pylint, pycodestyle, pydocstyle

Các công cụ về Linting ở đây và các công cụ về type-checker, format code có nhiều điểm tương đồng và chồng chéo lẫn nhau, nhưng ở đây Linting xét về tính logic như sử dụng dư thừa thư viện, biến, hoặc các biểu thức logic dư thừa …

Trong khía cạnh này thì `pycodestyle` có phần chiếm ưu thế vì tốc độ thực thi nhanh và khả năng bắt lỗi tốt. Phần linting được trình bày sau bởi vì nếu bạn sử dụng type-checker và format code tự động thì phần linting còn lại sẽ chỉ tập trung vào tính logic của mã nguồn, mặc dù có thể có trùng lắp tính năng nhưng không sao, thà thừa hơn thiếu.

Fullstack Station Tips

Việc tuân thủ coding-standard là cực kỳ quan trọng đảm bảo tính nhất quán theo chuẩn của dự án và hạn chế các lỗi phát sinh ngoài ý muốn. Trong đó viết code theo type-annotations là quan trọng nhất vì có nhiều hiệu quả, còn các thứ khác đa phần là được giải quyết tự động thông qua việc format code và sửa theo gợi ý của các công cụ Linting.

Mỗi khi mình viết code, mà không có type-annotations thì chắc chắn 1 điều là mình hiểu chưa tốt các kiểu dữ liệu của các bộ thư viện đang sử dụng hoặc chính mã nguồn của dự án. Điều này xảy ra khi mình học thêm các thư viện bên mảng Machine Learning như Numpy, Pandas, Pytorch, dẫn tới là 1 áp lực phải học, hiểu rõ các kiểu dữ liệu của các thư viện này.

Bộ công cụ mà mình sử dụng là: mypy, Black và pycodestyle, pytype.

(Pyright là công cụ mới nổi lên từ cuối tháng 3/2019, mình sẽ sử dụng xem như thế nào và báo cáo mọi người sau)

Tham khảo

https://realpython.com/python-code-quality/

https://medium.com/@CodingZen/codingzen-static-typing-in-python-no-way-afb643c334f

The post Giới thiệu một số công cụ hỗ trợ lập trình Python appeared first on Fullstack Station.

]]>
https://fullstackstation.com/gioi-thieu-mot-so-cong-cu-ho-tro-lap-trinh-python/feed/ 1