Mô-đun gõ python

Từ khi đi học đến lúc đi đảm bảo chúng ta cũng được học qua vài ba ngôn ngữ lập trình như java, c, c++, php, javascript. Nhưng chúng ta có thể biết và không để ý thì chúng ta được chia làm 2 loại là Staticly typed và Dynamically typed

Các ngôn ngữ được gõ tĩnh có thể hiểu là khi khai báo hàm và các tham số của nó thì kiểu dữ liệu của nó phải được biết tại thời điểm biên dịch. Điều này có nghĩa là khi chúng ta thiết lập chương trình, chúng ta phải khai báo kiểu thông báo của biến một cách tường minh. Một số ngôn ngữ thuộc kiểu này như C, C++, Java

Ngôn ngữ gõ động được hiểu là kiểu của biến được liên kết với giá trị lúc chạy. Điều này có nghĩa là khi lập trình chúng ta không cần khai báo kiểu thông báo của một biến. Với một biến được khai báo, chúng ta có thể tùy ý gán gía trị bất kỳ cho nó mà không cần quan tâm đến kiểu của nó là gì. Nó sẽ tự động ép kiểu khi nhận được giá trị. Một số ngôn ngữ cùng loại có kiểu như vậy. Ruby, PHP, JavaScript, trăn

It could found Python thuộc loại Dynamically typed languages. Không cần quan tâm đến kiểu dữ liệu đầu vào, điều này sẽ giúp chúng ta viết mã nhanh hơn một chút. Nhưng đi kèm với điều đó trong nhiều trường hợp nó sẽ không được tường minh và làm cho chúng ta bối rối trong quá trình gỡ lỗi. Một lần đầu vào tùy biến sẽ làm chúng ta mất nhiều thời gian về những trường hợp của nó có thể xảy ra

Phiên bản python 3. 5. Python cho ra mắt một tính năng là Type Hints. Mục đích là cung cấp một cú pháp tiêu chuẩn cho kiểu chú thích của dữ liệu đầu vào và đầu ra. Điều này thì được khuyến khích chứ không phải là bắt buộc để không làm thay đổi bản chất của các ngôn ngữ được gõ động

II. Cách sử dụng

1. Chú thích biến

Biến thông thường sẽ được gán như sau

a = 3
b = 3.14
c = 'abc'
d = False
e = ['a', 'b', 'c']
f = (1, 2, 3)
g = {'a': 1, 'b': 2}

Nhưng chúng ta có thể chú thích để người sau đọc có thể dễ dàng hình dung hơn

a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False
e: list = ['a', 'b', 'c']
f: tuple = (1, 2, 3)
g: dict = {'a': 1, 'b': 2}

Nếu gán biến bình thường mà viết thế này thì sẽ rất dài dòng và có thể làm cho chúng ta thấy ghét. Nhưng nếu viết bên trong hàm thì có thể hữu ích hơn

>>> def add_number(p1: int = 1, p2: int = 2):
..     p3: int = 3
..     return p1+p2+p3
.. 
>>> add_number()
6

Nếu nhìn đơn giản có thể thấy là biến p3 kiểu chú thích sẽ không có tác dụng gì nhiều. Nhưng hãy thử nghĩ nếu 1 hàm quá dài và nhiều biến. Với việc gán lại công việc có thể sẽ làm sai kiểu dữ liệu chúng ta mong muốn. Thì khi nhìn vào chức năng với chú thích như vậy sẽ tốt hơn công việc phải gỡ lỗi lại từ đầu xem biến đó nên là kiểu dữ liệu gì

2. Chú thích chức năng

Please started with job not used type hints

>>> def add_two_param(p1, p2):
..     return p1 + p2

>>> print(add_two_param(3, 5))
8
>>> type(add_two_param(3,5))


>>> print(add_two_param("thai", "son"))
thaison
>>> type(add_two_param("thai", "son"))

Cũng không có gì đặc biệt ở đây. Có thể thấy cùng một hàm mà ta có thể truyền nhiều giá trị đầu vào và kết quả có thể trả về nhiều kiểu dữ liệu khác nhau

Để sử dụng kiểu gợi ý và muốn lưu ý rằng đối số truyền vào cần phải là kiểu int và kết quả trả về cũng là kiểu int thì chúng ta làm như sau

>>> def add_two_param(p1: int, p2: int) -> int:
..     return p1 + p2

To add default value for variable

>>> def add_two_param(p1: int = 10, p2: int = 20) -> int:
..     return p1+p2
.. 
>>> add_two_param()
30

3. gõ mô-đun

Việc gõ mô-đun của python có thể làm cho việc khai báo trở nên dài hơn dòng

Đối xứng với biến

from typing import List, Tuple, Dict
e: List[str] = ['a', 'b', 'c']
f: Tuple[int, int, int] = (1, 2, 3)
g: Dict[str, int] = {'a': 1, 'b': 2}

Đối với chức năng

def squre(arr: List[float]) -> List[float]:
    return [x ** 2 for x in arr]
print(squre([1, 2, 3])) # 1, 4, 9

Có thể tùy chọn biến đầu vào là int hoặc float bằng cách sử dụng toán tử

>>> def add_number(p1: int = 1, p2: int = 2):
..     p3: int = 3
..     return p1+p2+p3
.. 
>>> add_number()
6
6

def square(arr: List[Union[int, float]]) -> List[Union[int, float]]:
    return [x ** 2 for x in arr]
print(squre([1, 2, 3])) # 1, 4, 9

Làm như gấu trúc thì có thể cho chúng ta biết là nó chấp nhận đầu vào là int hoặc float và có thể trả về là int hoặc float. Còn rất nhiều tùy chọn khác để có thể phù hợp với bài toán. Các bạn có thể tham khảo tại đây

4. mypy

Tất cả những gì ở trên bài viết là để chú thích cho 1 hàm, 1 hàm dễ học hơn. Những người đọc code của chúng ta sẽ cảm thấy dễ chịu hơn. Nhưng nếu không có cũng không sao. Một công việc khác là nếu chúng ta chú thích sai thì điều này sẽ khiến mọi công việc trở nên tồi tệ hơn. Rõ ràng chú thích đầu vào kiểu int, mà kiểu int truyền vào bị sai. Do vậy mình xin giới thiệu một thư viện là mypy. Nó sẽ giúp chúng tôi xác thực tất cả những gì chúng tôi thích. Nếu không chú thích gì thì nó sẽ bỏ qua. Ví dụ. test_hint. py

a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False
e: list = ['a', 'b', 'c']
f: tuple = (1, 2, 3)
g: dict = {'a': 1, 'b': 2}
0

When this file run with mypy, results as after

a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False
e: list = ['a', 'b', 'c']
f: tuple = (1, 2, 3)
g: dict = {'a': 1, 'b': 2}
0

Nó bắt đầu xác thực và thông báo rõ ràng rằng đầu vào chấp nhận là int mà truyền vào float

If they ta edit file python on as after

a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False
e: list = ['a', 'b', 'c']
f: tuple = (1, 2, 3)
g: dict = {'a': 1, 'b': 2}
1

Khi chạy lại mypy

a: int = 3
b: float = 3.14
c: str = 'abc'
d: bool = False
e: list = ['a', 'b', 'c']
f: tuple = (1, 2, 3)
g: dict = {'a': 1, 'b': 2}
2

III. Kết luận

Việc sử dụng loại gợi ý là vừa có mặt lợi vừa có hại. Mặt lợi là giúp chúng ta gỡ lỗi, kiểm tra lỗi dễ dàng hơn. Mã đọc sẽ dễ hiểu hơn. Nhưng mặt hại thì làm mã trở lên dòng dài, tốn thời gian. Nên sử dụng nó một cách linh hoạt sẽ giúp công việc của chúng ta trở nên nhanh chóng hơn

Với tôi, tôi thường sử dụng nó trong công việc khai báo hàm, đối với biến thì rất ít khi. Hãy giữ mã gọn gàng và dễ đọc nhất. cảm ơn đã đọc bài viết