- vừa được xem lúc

Python: Đây là tính năng chứ không phải bug (P1)

0 0 23

Người đăng: Sang Hà Ngọc

Theo Viblo Asia

Python làm một ngôn ngữ khá dễ tiếp cận cho người mới tuy nhiên thì với Python thì cũng có khá nhiều thứ khá nhì nhằng và bài viết này sẽ giúp các bạn hiểu thêm về mấy cái nhì nhằng này. Dưới đây là một số tính năng khá vi diệu có trong Python (Lưu ý đây là tính năng chứ không phải bug).

1. Cấu trúc for-else.

Nhiều ngôn ngữ lập trình có cấu trúc if-else để xử lý các câu lệnh điều kiện. Tuy nhiên, trong Python, bạn thậm chí có thể sử dụng câu lệnh else mà không cần if.

animals = ["Dog", "Cat", "Pig"] for animal in animals: if animal == "Chicken": print("Chicken is an animal!") break
else: print("Not found Chicken!") # Not found Chicken!

Ví dụ, đoạn mã trên không có câu lệnh if. Nhưng khối mã bên dưới câu lệnh else đã được thực thi thành công!

Đây là cú pháp for-else trong Python.

Đó là một tính năng kỳ lạ và chúng ta nên cẩn thận khi sử dụng nó. Nhưng ý tưởng của nó lại đơn giản đến không ngờ:

Khối else sẽ được thực thi khi vòng lặp for chạy mà không gặp break.

Để chứng minh điều này, hãy xem xét đoạn code sau:

animals = ["Dog", "Cat", "Pig", "Chicken"] for animal in animals: if animal == "Chicken": print("Chicken is an animal!") break
else: print("Not found Chicken!") # Chicken is an animal!

Khi chạy đoạn code trên, danh sách animals chứa “Chicken” vì vậy, vòng lặp for đã bị break và câu lệnh else không được thực thi.

2. Thay đổi Tuples trong Python ?

Như đã biết thì tuples là immutable Python objects (tức là đối tượng không thể thay đổi được). Tuy nhiên thì có một mẹo có thể tạm coi là thay đổi tuples mặc dù thực tế thì bản chất tuples không hề thay đổi.

Nhưng theo cách dưới đây thì ta có thể tạm coi là tuples được thay đổi.

tp = ([1, 2, 3], 4, 5)
tp[0].append(4)
print(tp)
# ([1, 2, 3, 4], 4, 5)

giải thích cho điều này thì tp là một immutable Python objects (bất biến). Tuy nhiên, phần tử đầu tiên trong tp là một list có thể thay đổi được. Khi này, phần tử đầu tiên của tp sẽ trỏ vào địa chỉ ô nhớ lưu trữ list mà có giá trị là [1, 2, 3] ban đầu. Khi ta thay đổi giá trị của phần tử đầu tiên thì tp không đổi tuy nhiên thì ta vẫn có thể coi là tp thay đổi (thay đổi về mặt giá trị trả ra). Các bạn có thể xem xét ví dụ dưới đây để thấy rõ hơn:

a = [1, 2, 3]
tp = (a, 4, 5)
print(id(a) ==id(tp[0]))
# True
a.append(4)
print(id(a) == id(tp[0]))
print(tp)
# True
# ([1, 2, 3, 4], 4, 5)

3. 256 là 256, nhưng đôi khi 257 không phải 257

Ngạc nhiên chưa, đây là một tính năng ảo diệu của python chứ hoàn toàn không phải lỗi. Khi chạy ví dụ dưới đây với python shell thì kết quả trả ra sẽ khiến bạn bất ngờ.

>>> a=256
>>> b=256
>>> a is b
True
>>> x = 257
>>> y = 257
>>> print(x is y)
False
>>>

Về cơ bản, Python tải trước tất cả các số nguyên nhỏ trong phạm vi [-5, 256] để tiết kiệm thời gian và chi phí bộ nhớ. Do đó, khi một số nguyên trong phạm vi này được khai báo, Python chỉ tham chiếu số nguyên được lưu trong bộ nhớ cache và sẽ không tạo bất kỳ đối tượng mới nào. Với mỗi dòng code là một câu lệnh hoàn toàn khác, được phân tích cú pháp và biên dịch riêng, do đó xảy ra trường hợp như trên.

Trong một từ, ab là cùng một đối tượng, nhưng xy là hai đối tượng khác nhau.

>>> id(a)
1696073345424
>>> id(b)
1696073345424
>>> id(x)
1696122928496
>>> id(y)
1696122928752

Cơ chế này trong Python được gọi là integer interning hoặc integer caching. Đấy là khi chúng ta viết code trong python shell thì sẽ xảy ra trường hợp này còn khi chúng ta viết chúng trong cùng 1 file, cùng một ngữ cảnh (context), trình biên dịch (complier) thì sẽ không xảy ra trường hợp này.

4. String interning

String interning làm cho các hoạt động xử lý chuỗi phổ biến tiết kiệm thời gian và không gian bằng cách lưu chúng vào bộ nhớ đệm. Thay vì mỗi lần tạo một bản sao mới của chuỗi, phương pháp tối ưu hóa này yêu cầu chỉ giữ một bản sao của chuỗi cho mọi giá trị riêng biệt bất biến thích hợp và sử dụng tham chiếu con trỏ ở bất kỳ đâu được gọi.

x = "This is a string"
y = "This is a string"
print(x is y) # prints True

Toán tửis trong Python được sử dụng để kiểm tra xem hai đối tượng có tham chiếu đến cùng một vị trí bộ nhớ hay không. Nếu nó trả về True, điều đó có nghĩa là hai đối tượng thực sự là cùng một đối tượng. Tong đoạn code trên, thay vì tạo một bản sao mới khi y được gán cho một chuỗi có cùng giá trị với x, Python trỏ đến cùng một chuỗi được gán cho x. Điều này chỉ đúng với các chuỗi nhỏ hơn; các chuỗi lớn hơn sẽ tạo các bản sao riêng lẻ như bình thường.

x = "This is a string" * 300
y = "This is a string" * 300
print(x is y) # False

Điều này sẽ in ra False trên console và các chuỗi không được interning. Và dưới đây là giải pháp:

import sys
x = sys.intern("This is a string" * 300)
y = sys.intern("This is a string" * 300)
print(x is y) # True

5. 0.1+0.2 is not 0.3

Trong thực tế thì mọi người đều biết là0.1 + 0.2 = 0.3 tuy nhiên thì Python lại không nghĩ như vậy:

print(0.1+0.2==0.3)
print(0.1+ 0.2)
# False
# 0.30000000000000004

Thực tế mà nói, đây không phải là lỗi của Python. Không máy tính nào có thể tính toán giá trị float một cách chính xác.

Máy tính chỉ có thể lưu trữ và xử lý các số thực với độ chính xác nhất định. Vì vậy, các hoạt động của float dựa vào việc triển khai phần cứng trong chip xử lý của máy và không có ngôn ngữ lập trình nào có thể chắc chắn rằng các phép tính với float luôn được tính đúng.

Nguồn:

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Regular Expression và cuộc đời bạn sẽ bớt khổ (Updated v2.2)

. Regular Expression (RegEx) à? Nghe quen quen. . Bạn cần xử lý validate (kiểm tra tính hợp lệ) các trường dữ liệu nhập vào ô Text. .

0 0 109

- vừa được xem lúc

Đề thi interview DevOps ở Châu Âu

Well. Chào mọi người, mình là Rice - một DevOps Engineers ở đâu đó tại Châu Âu.

0 0 88

- vừa được xem lúc

12 best practices với VueJS

Giới thiệu. Xin chào tất cả các bạn, hôm nay mình sẽ giới thiệu với các bạn một số lưu ý khi coding vuejs. Không dài dòng nữa mình bắt đầu luôn nhé. Vì sao cần phải sử dụng :key , vì nó sẽ giúp giữ lại các state của component.

0 0 197

- vừa được xem lúc

Những điều cần lưu ý và sử dụng Hook trong React (Phần 2)

II. UseEffect và điều cần lưu ý . Có hai loại xử lý phổ biến trong các thành phần React: những xử lý phụ không yêu cầu cleanup và những xử lý phụ có cleanup. Hãy xem xét sự khác biệt này chi tiết hơn.

0 0 129

- vừa được xem lúc

[Python] Một số tips khi code (Phần 2)

Hi, trong phần trước mình đã giới thiệu đến các bạn 9 tips khi các bạn code Python. Trong phần này mình sẽ tiếp tục gửi đến các bạn một số tips hữu dụng khác nhé. Let's go. Để reverse một đoạn string, chúng ta dùng var[::-1].

0 0 49

- vừa được xem lúc

Không có gì là miễn phí cả

Mình có cái tật rất xấu. Đấy là hay cố gắng tìm hướng giải quyết cho người khác.

0 0 42