10

A purefunction là một chức năng tương tự như chức năng Toán học, nơi không có tương tác với "thế giới thực" cũng như các tác dụng phụ. Từ quan điểm thực tế hơn của xem, nó có nghĩa là một chức năng tinh khiết có thể không:Làm cách nào để kiểm tra xem hàm có thuần trong Python không?

  • In hoặc hiển thị một thông
  • Hãy ngẫu nhiên
  • Depend on thời gian hệ thống
  • Thay đổi các biến toàn cục
  • Và những người khác

Tất cả những hạn chế này giúp dễ dàng hơn để giải thích về hàm thuần túy s hơn là những người không thuần khiết. Phần lớn các chức năng sau đó sẽ được tinh khiết để chương trình có thể có ít lỗi hơn.

Trong các ngôn ngữ có hệ thống loại lớn như Haskell, người đọc có thể biết ngay từ đầu nếu chức năng là hoặc không thuần túy, giúp việc đọc liên tục dễ dàng hơn.

Trong Python, thông tin này có thể được mô phỏng bởi trình trang trí @pure được đặt ở trên cùng của hàm. Tôi cũng muốn rằng trang trí để thực sự làm một số công việc xác nhận. Vấn đề của tôi nằm trong việc thực hiện một trang trí như vậy.

Hiện tại, tôi chỉ cần tìm mã nguồn của hàm cho các từ khóa như global hoặc random hoặc print và than phiền nếu tìm thấy một trong số chúng.

import inspect 

def pure(function): 
    source = inspect.getsource(function) 
    for non_pure_indicator in ('random', 'time', 'input', 'print', 'global'): 
     if non_pure_indicator in source: 
      raise ValueError("The function {} is not pure as it uses `{}`".format(
       function.__name__, non_pure_indicator)) 
    return function 

Tuy nhiên, bạn có thể làm việc này tùy thuộc vào may mắn của mình, bạn có thể giúp tôi viết một trang trí đẹp hơn không?

+3

Bạn có thể 'inspect.getsource' rồi' ast.parse' và đi bộ kiểm tra các nút khác nhau ... nhưng bạn sẽ đi ngược lại lý do ngôn ngữ tồn tại - xem xét sử dụng mô đun 'abc' nếu bạn muốn , sau đó 'isinstance' kiểm tra xem cần ở đâu ... - python được ** gõ mạnh ** - không ** tĩnh ** gõ –

+0

@JonClements ngôn ngữ động thực tế thực hiện xác minh biên dịch ít hơn, nhưng tôi nghĩ đó là kiểm tra cụ thể sẽ tăng cường rất nhiều tổ chức chương trình và kiểm tra lại sự hiểu biết của các lập trình viên về công việc của mình. – Caridorc

+4

Sau đó, sử dụng một ngôn ngữ gõ tĩnh ... :) Bạn có thể xem nó như là một điều * xấu * hoặc một điều * tốt ... nhưng đó là cách nó là –

Trả lời

9

Tôi thấy bạn đến từ đâu nhưng tôi không nghĩ điều này có thể hiệu quả.Hãy lấy một ví dụ đơn giản:

def add(a,b): 
    return a + b 

Vì vậy, điều này có thể trông "thuần khiết" đối với bạn. Nhưng trong Python + ở đây là một chức năng tùy ý có thể làm bất cứ điều gì, chỉ phụ thuộc vào các ràng buộc có hiệu lực khi nó được gọi. Vì vậy, a + b có thể có các tác dụng phụ tùy ý.

Nhưng thậm chí còn tệ hơn thế. Ngay cả khi điều này chỉ làm tiêu chuẩn số nguyên + sau đó có nhiều 'không tinh khiết' công cụ đang xảy ra.

+ đang tạo đối tượng mới. Bây giờ nếu bạn chắc chắn rằng chỉ có người gọi có một tham chiếu đến đối tượng mới đó thì có một cảm giác mà trong đó bạn có thể nghĩ về điều này như một hàm thuần túy. Nhưng bạn không thể chắc chắn rằng, trong quá trình tạo ra đối tượng đó, không có tham chiếu đến nó bị rò rỉ.

Ví dụ:

class RegisteredNumber(int): 

    numbers = [] 

    def __new__(cls,*args,**kwargs): 
     self = int.__new__(cls,*args,**kwargs) 
     self.numbers.append(self) 
     return self 

    def __add__(self,other): 
     return RegisteredNumber(super().__add__(other)) 

c = RegisteredNumber(1) + 2 

print(RegisteredNumber.numbers) 

này sẽ cho thấy tiện ích được cho là tinh khiết chức năng đã thực sự thay đổi trạng thái của lớp RegisteredNumber. Đây không phải là một ví dụ giả tạo ngớ ngẩn: trong cơ sở mã sản xuất của tôi, chúng tôi có các lớp theo dõi từng cá thể được tạo, ví dụ, để cho phép truy cập thông qua khóa.

Khái niệm về độ tinh khiết không có ý nghĩa nhiều trong Python.

0

(không phải là một câu trả lời, nhưng quá dài cho một bình luận)

Vì vậy, nếu một hàm có thể trả về giá trị khác nhau cho cùng một tập các đối số, nó không phải là tinh khiết?

Hãy nhớ rằng chức năng trong Python là những đối tượng, vì vậy bạn muốn kiểm tra độ tinh khiết của một đối tượng ...

Hãy ví dụ này:

def foo(x): 
    ret, foo.x = x*x+foo.x, foo.x+1 
    return ret 
foo.x=0 

gọi foo(3) nhiều lần cho:

>>> foo(3) 
9 

>>> foo(3) 
10 

>>> foo(3) 
11 

...

Ngoài ra, đọc các hình ảnh chung không yêu cầu sử dụng câu lệnh global hoặc nội dung dựng sẵn global() bên trong chức năng của bạn. Biến toàn cầu có thể thay đổi ở một nơi khác, ảnh hưởng đến độ tinh khiết của hàm của bạn.

Tất cả tình huống trên có thể khó phát hiện khi chạy.

+0

Ý tưởng thú vị, nhưng tôi có thể nghĩ về nhiều chức năng không thuần khiết, có vẻ như quá thời gian ngắn như nhận giờ trong ngày, Số phiên bản o/s, chi nhánh git hiện tại, v.v. – wallyk

Các vấn đề liên quan