Lười biếng trong python là gì?

Đánh giá lười biếng là một chiến lược đánh giá giữ đánh giá một biểu thức cho đến khi cần giá trị của nó. Nó tránh đánh giá lặp đi lặp lại. Haskell là một ví dụ điển hình về ngôn ngữ lập trình chức năng mà các nguyên tắc cơ bản của nó dựa trên Đánh giá lười biếng

Đánh giá lười biếng được sử dụng trong các chức năng bản đồ Unix để cải thiện hiệu suất của chúng bằng cách chỉ tải các trang được yêu cầu từ đĩa. Sẽ không có bộ nhớ nào được phân bổ cho các trang còn lại

Đánh giá lười biếng - Ưu điểm

  • Nó cho phép bộ thực thi ngôn ngữ loại bỏ các biểu thức con không được liên kết trực tiếp với kết quả cuối cùng của biểu thức

  • Nó làm giảm độ phức tạp về thời gian của một thuật toán bằng cách loại bỏ các phép tính tạm thời và các điều kiện

  • Nó cho phép lập trình viên truy cập các thành phần của cấu trúc dữ liệu không theo thứ tự sau khi khởi tạo chúng, miễn là chúng không có bất kỳ phụ thuộc vòng tròn nào

  • Nó phù hợp nhất để tải dữ liệu sẽ được truy cập không thường xuyên

Đánh giá lười biếng - Nhược điểm

  • Nó buộc thời gian chạy ngôn ngữ giữ việc đánh giá các biểu thức con cho đến khi nó được yêu cầu trong kết quả cuối cùng bằng cách tạo thunks [đối tượng bị trì hoãn]

  • Đôi khi nó làm tăng độ phức tạp không gian của một thuật toán

  • Rất khó để tìm thấy hiệu suất của nó vì nó chứa rất nhiều biểu thức trước khi thực hiện

Đánh giá lười biếng bằng Python

Phương thức phạm vi trong Python tuân theo khái niệm Đánh giá lười biếng. Nó tiết kiệm thời gian thực hiện cho các phạm vi lớn hơn và chúng tôi không bao giờ yêu cầu tất cả các giá trị cùng một lúc, vì vậy nó cũng tiết kiệm mức tiêu thụ bộ nhớ. Hãy xem ví dụ sau

Sự lười biếng trong các ngôn ngữ lập trình là điều gì đó đã xảy ra khá nhiều trong thời gian gần đây. Chắc chắn có vẻ như rất nhiều người muốn nó được triển khai bằng ngôn ngữ yêu thích của họ. Điều này thường xảy ra sau khi đã sử dụng nó trong Haskell, nơi nó cực kỳ hữu ích, dễ hiểu và dường như không có bất kỳ cạm bẫy nghiêm trọng nào

Tôi đã chơi xung quanh với các công cụ trang trí trong Python và sự lười biếng dường như là thứ sẽ tạo nên một thử nghiệm tốt. Khái niệm đánh giá lười biếng thực sự không khó lắm; . Thấy rằng python coi các hàm là cấu trúc bậc cao, tôi. e, không khó để triển khai chức năng cho một hàm trả về một hàm, sẵn sàng để được đánh giá khi cần

Nhưng điều này là không thực sự đủ. Tôi muốn một cách để sự lười biếng thực sự minh bạch, tốt nhất là chỉ sử dụng một công cụ trang trí và đó là tất cả. Đối với điều này, giải pháp không rõ ràng ngay lập tức, nhưng python là một ngôn ngữ linh hoạt, vì vậy tôi nghĩ có thể có cơ hội. Với tất cả những điều này trong đầu, tôi đã suy nghĩ rất lâu về việc đánh giá lười biếng trong python và cuối cùng đã quyết định một vài điều

  1. Sẽ không thể thêm sự lười biếng trong suốt mà không thao tác rộng rãi mã byte hoặc phần bên trong nghiêm trọng của trình biên dịch. Cả hai điều tôi không muốn làm
  2. Đánh giá lười biếng minh bạch không thực sự là một ý tưởng hay trong một ngôn ngữ mệnh lệnh

Tôi sẽ bắt đầu với điểm đầu tiên. Hãy xem xét một số ví dụ, bắt đầu với trang trí lười biếng của tôi

def lazy[func]:
    def lazyfunc[*args, **kwargs]:
        wrapped = lambda x : func[*args, **kwargs]
        wrapped.__name__ = "lazy-" + func.__name__
    return wrapped
return lazyfunc

Đây là một điều khá đơn giản - cách điển hình để mô phỏng đánh giá lười biếng. Đưa ra một chức năng, nó trả về một chức năng mới, khi được gọi, đánh giá chức năng được truyền ban đầu

Chúng ta có thể sử dụng điều này như một trang trí trong những điều sau đây

def hello_add_normal[x, y]:
	print "Hello I am Normal!"
	return x + y

@lazy
def hello_add_lazy[x, y]:
	print "Hello I am Lazy!"
	return x + y

Thực thi chức năng đầu tiên sẽ đánh giá nó, nhưng chức năng thứ hai thực hiện một cuộc gọi bổ sung, được sử dụng khi chúng tôi yêu cầu giá trị thực của đánh giá. Bằng cách này, chúng ta có thể đánh giá kết quả khi chúng ta muốn [hoặc khi cần thiết, trong trường hợp lười biếng]

$ hello_add_normal[1, 2]
Hello I am Normal!
3
$ hello_add_lazy[1, 2]

$ myval = hello_add_lazy[1, 2]
$ myval[]
Hello I am Lazy!
3

Tại thời điểm này, lập trình viên người dùng hoàn toàn có thể thêm lệnh gọi bổ sung này [hoặc hàm "bắt buộc"] bất cứ khi nào họ muốn đánh giá, nhưng tôi đang tìm cách nào đó để python biết khi nào cần và thực hiện

Vì vậy, mẹo thực sự ở đây là thêm lệnh gọi bổ sung này vào bất kỳ thời điểm nào khi giá trị của hàm này được yêu cầu. Thật không may, điều này yêu cầu phân tích mã. Điều gì đó có thể xảy ra trong thời gian chạy python, nhưng chỉ ở cấp mã byte

Tuy nhiên, có lẽ điều này là đủ, tất cả đều nhân danh sự lười biếng đánh giá. ? . Chúng tôi muốn thêm một cuộc gọi bổ sung trước khi chuyển nhượng cho myval - sau khi chúng tôi vừa nhìn vào một biểu tượng mà chúng tôi biết là lười biếng. Vì mã python dựa trên ngăn xếp, nên có vẻ như bạn chỉ cần thêm một mã byte "gọi" bổ sung, sau khi xuất hiện bất kỳ biểu tượng "lười biếng" nào ở đầu ngăn xếp. Tuy nhiên, trong thực tế, mọi thứ trở nên khó khăn hơn một chút. Thật khó để theo dõi những gì ở cấp cao nhất của ngăn xếp và có nhiều sự phức tạp khác. Hãy xem ví dụ này

mylist = [hello_add_lazy[1,2], hello_add_lazy[2,5], hello_add_lazy[6,1]]
hello = mylist[0]

Tại thời điểm này, nơi duy nhất chúng tôi đã tham chiếu đến biểu tượng "lười biếng" trong mã byte là trên cấu trúc danh sách, không có nơi nào gần nơi chúng tôi thực sự muốn thực hiện đánh giá tự động. Vì vậy, trong trường hợp này, chúng tôi phải theo dõi "danh sách những điều lười biếng" này và xem xét cả điều đó.  

Chắc chắn, ví dụ này vẫn có thể giải quyết và suy luận, nhưng với các cấu trúc dữ liệu phức tạp tùy ý, các hàm xây dựng, hàm bậc cao và nhiều cấu trúc python phức tạp khác, tôi cảm thấy nó không đáng

Mã byte bị loại bỏ quá xa khỏi mô hình ngữ nghĩa của ngôn ngữ đối với loại phân tích này. Nếu bạn muốn đánh giá lười biếng một cách nghiêm túc thì nó phải được thực hiện trong trình biên dịch, điều này đưa tôi đến điểm thứ hai. Có lẽ chúng tôi thậm chí không muốn đánh giá lười biếng tự động

Python có hai biểu thức ngữ nghĩa có lẽ là mạnh nhất trong ngôn ngữ, đó là gán "=" và gọi "[]". Không cần phải nói, lộn xộn với những thứ này có lẽ không phải là ý tưởng tốt nhất. Thật không may đánh giá lười biếng làm cả hai. Hãy xem một ví dụ khác

def sleepy[x]:
	time.sleep[1]
	return x
	
$ my_other_list = [sleepy[1], sleepy[2], sleepy[3]]
[1,2,3]

Khi chạy, mã này ngủ trong ba giây rồi trả về danh sách [1,2,3]. Điều này không hề lười biếng chút nào, nhưng bạn có muốn nó làm bất cứ điều gì khác không? . Dấu ngoặc sau từ "sleepy" có nghĩa là hàm đang được gọi, bạn muốn nó được đánh giá. Đánh giá lười biếng gây rối với khái niệm này

Bài tập cũng bị nhầm lẫn, hãy xem một ví dụ khác

the_time = time.time[]
time.sleep[1]
next_time = time.time[]

if the_time == next_time: print "BOOM"

Trong ví dụ này, tôi sẽ không muốn mã in ra "BOOM". Với việc đánh giá càng lười biếng càng tốt, nó sẽ. Tốt thôi, bạn nói, nhưng điều gì sẽ xảy ra nếu chúng ta đánh giá việc gán cho biến thay vào đó, để giữ đúng thứ tự. Chà, điều này giống như muốn kết hợp giữa thuần túy và không thuần túy, và cuối cùng, theo đối số này có nghĩa là cuối cùng bạn phải đánh giá việc gán cho BẤT KỲ cấu trúc dữ liệu nào, không chỉ các biến và điều này không hề lười biếng . Chuyển nhượng không có nghĩa là tương đương và chuyển nhượng cùng một lúc

Trong một ngôn ngữ như Haskell, loại mã này sẽ không thể thực hiện được nếu không có các đơn nguyên. Điều này là do trong Haskell không có tác dụng phụ trong các chức năng, không có cảm giác về thứ này thì thứ khác. Ngủ, in, tất cả những thứ đó sẽ không thể khai báo trong một chức năng và do đó, với việc đánh giá lười biếng, đó không phải là vấn đề. Không nhầm lẫn khi sự việc xảy ra

Đây không phải là trường hợp trong python. Lập trình không có tác dụng phụ rất khó và không phải lúc nào cũng là phương pháp ưa thích [ít nhất là đối với tôi]. Không có gì sai với các tác dụng phụ miễn là bạn biết nhiệm vụ và chức năng gọi thực sự có ý nghĩa gì về mặt ngữ nghĩa. Và dù sao đi nữa, chẳng phải việc biết khi nào các chức năng của bạn đang được gọi sẽ rõ ràng và dễ chịu hơn nhiều sao?

Đánh giá lười biếng là điều tuyệt vời trong Haskell, nhưng nó không phải là loại "tính năng ngôn ngữ" có thể và nên được thêm vào các ngôn ngữ theo ý thích. Hầu hết các hành vi đánh giá lười biếng có thể được mô phỏng thông qua các phương tiện khác, mà tôi nghĩ là cần thiết trong sự rõ ràng của chúng khi không xử lý một ngôn ngữ thuần túy, không có tác dụng phụ, chẳng hạn như Haskell

Chức năng lười biếng là gì?

Lập trình hàm và Lambda- Tìm hiểu Java8 bằng cách viết mã . Nó tránh đánh giá lặp đi lặp lại. Haskell là một ví dụ điển hình về ngôn ngữ lập trình chức năng mà các nguyên tắc cơ bản của nó dựa trên Đánh giá lười biếng. an evaluation strategy which holds the evaluation of an expression until its value is needed. It avoids repeated evaluation. Haskell is a good example of such a functional programming language whose fundamentals are based on Lazy Evaluation.

lười biếng có nghĩa là gì trong lập trình?

Tóm lại, "lười biếng" có nghĩa là trì hoãn một hành động cho đến khi cần thiết, nếu có . Nếu kết quả của hành động không bao giờ được sử dụng, thì hành động đó sẽ không bao giờ được thực hiện, tiết kiệm một số công việc.

Khởi tạo lười biếng trong Python là gì?

Trong lập trình máy tính, lười khởi tạo là chiến thuật trì hoãn việc tạo đối tượng, tính toán giá trị hoặc một số quy trình tốn kém khác cho đến khi cần đến lần đầu tiên< . Đó là một loại đánh giá lười biếng đề cập cụ thể đến việc khởi tạo các đối tượng hoặc các tài nguyên khác. . It is a kind of lazy evaluation that refers specifically to the instantiation of objects or other resources.

Python háo hức hay lười biếng?

Python thường háo hức nhưng chúng ta có thể tận dụng các hàm trình tạo để tạo đánh giá lười biếng. Hàm map[] lười biếng. với hai hàm map[], một mục sẽ được lấy từ x, được xử lý bởi hàm g[], sau đó được xử lý bởi hàm f[].

Chủ Đề