Phương pháp ví dụ trang trí python

Các nhà trang trí đã thêm quy ước cú pháp ngọt ngào và thuận tiện vào ngôn ngữ Python và làm cho việc mã hóa trở nên thú vị và hiệu quả hơn trong Python. Trong hai hướng dẫn trước, tôi đã chỉ cho bạn cách làm việc với hàm trang trí trong Python. Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách áp dụng trình trang trí cho các phương thức và lớp

Trước khi bắt đầu

Đây không phải là hướng dẫn dành cho người mới bắt đầu. Xem qua mã hiển thị ở đây có thể không yêu cầu nhiều kiến ​​thức nâng cao về Python, nhưng để thực sự hiểu sâu về nó, bạn chắc chắn cần phải là một lập trình viên Python trung cấp hoặc cao cấp. Trước khi bạn tiếp tục, vui lòng kiểm tra danh sách sau

  • Chắc hẳn bạn đã đọc hai hướng dẫn trước về decorator và tự mình thực hành code
  • Bạn phải có kiến ​​thức Lập trình hướng đối tượng vững chắc trong Python
  • Bạn nên làm việc với các trình trang trí phương thức tích hợp sẵn trong Python
  • Bạn phải cài đặt Python 3 trên hệ thống của mình
  • Bạn nên làm quen với các chương trình dòng lệnh trong hệ thống của mình

Chuẩn bị môi trường

Để bắt đầu viết mã

  • Tạo một thư mục hoặc chọn một thư mục hiện có
  • Tạo một tệp có tên dec3. py trong thư mục đã chọn
  • Bắt đầu dòng lệnh của bạn trong thư mục hoặc cd vào đó
  • Chạy dec3. py để thấy rằng mọi thứ đều ổn với lệnh sau.
     $ python3 dec3.py

Sự khác biệt giữa các hàm và phương thức thuần túy

Tôi không muốn nói nhiều về chủ đề này vì tôi đã mong rằng bạn biết đây là những gì. Sự khác biệt cơ bản giữa các hàm và phương thức miễn phí trong Python là các phương thức được liên kết với các lớp/thể hiện của lớp đó và các hàm miễn phí không bị ràng buộc với bất kỳ thứ gì

Để giúp mọi thứ đơn giản hơn cho bạn, trong hướng dẫn này, chúng tôi sẽ giới hạn cuộc thảo luận về các trình trang trí trong các phương thức cá thể. Các phương thức tĩnh và phương thức lớp được tạo bằng cách trang trí chúng bằng các bộ trang trí staticmethod[] và classmethod[]. Các bộ mô tả cũng có trong trò chơi đồ vật và những thứ đó có liên quan đến cái này. Tôi có thể nói về các bộ mô tả trong Python trong hướng dẫn sau

Trang trí một phương thức sơ thẩm

Một phương thức thể hiện có một thể hiện được truyền cho nó trong khi gọi. Chúng tôi chỉ khai báo đó là tham số đầu tiên [thường là self]. Nhưng chúng ta không cần truyền đối số cho tham số đó khi gọi phương thức đó trên một đối tượng. Bản thân Python thực hiện nhiệm vụ. Vì vậy, nếu chúng ta muốn làm bất cứ điều gì với đối tượng cùng với phương thức, chúng ta có thể sử dụng nó bên trong trình trang trí của chúng ta

Giả sử chúng ta muốn in tên lớp và tên phương thức trên màn hình khi một phương thức được gọi. Chúng tôi muốn tạo một trang trí cho điều đó

def meth_decorator[method]:
   def method_wrapper[self, *args, **kwargs]:
       print[self.__class__.__name__ + "::" + method.__name__ + "[]:"]
       method[self, *args, **kwargs]
       print[]

   return method_wrapper

class C:
   @meth_decorator
   def say_hello[self, name]:
       print["Hello, %s" % name]

c = C[]
c.say_hello["Sabuj"]


This will output:

C::say_hello[]:
Hello, Sabuj

Nhìn vào method_wrapper[], tôi đã định nghĩa tham số đầu tiên là self để tôi có thể nắm bắt đối tượng đang gọi và tìm lớp từ đó. Nhưng trong trường hợp sử dụng của bạn nếu bạn không cần chúng thì có thể bỏ qua

Bây giờ, hãy tưởng tượng rằng bạn có hàng tá phương thức trong lớp và bạn muốn trang trí chúng. Bạn sẽ phải làm một cái gì đó như thế này

class C:
   @meth_decorator
   def say_hello[self, name]:
       print["Hello, %s" % name]

   @meth_decorator
   def say_bye[self, name]:
       print["Bye, %s" % name]

   @meth_decorator
   def say_go_fast[self, name]:
       print["Go fast, %s" % name]
...
...

Điều gì sẽ xảy ra nếu chúng ta có thể trang trí phương thức để trang trí tất cả các phương thức đó và loại bỏ trình trang trí phương thức lặp đi lặp lại

Trang trí lớp học

Vì chúng ta cần trả về một hàm hoặc có thể gọi được từ bên trong trình trang trí, nên chúng ta cần trả về một lớp từ bên trong trình trang trí lớp. Nhưng bản thân công cụ trang trí vẫn là một chức năng [mặc dù chúng ta có thể thực hiện theo cách khác với lớp nhưng điều đó có thể không trực quan đối với bạn và tôi không nghĩ đó là cách tốt để thực hiện những việc như vậy]

Hãy xác định chức năng trang trí và một lớp bên trong

def class_decorator[cls]:
   class WrapperClass:
       def __init__[self, *args, **kwargs]:
           self.instance = cls[*args, **kwargs]
...
...

Chức năng trang trí sẽ được thông qua một lớp. Bên trong WrapperClass, chúng ta đang tạo một thể hiện của lớp và lưu trữ nó trong thể hiện của biến thể hiện

Bây giờ, chúng ta cần trang trí các phương thức của thể hiện lớp. Nhưng chúng tôi không muốn tìm tất cả các phương thức, lặp lại chúng và trang trí. Thay vào đó, chúng tôi muốn trang trí chúng khi chúng được truy cập. Để làm điều này, chúng ta cần định nghĩa phương thức getattribute[] bên trong lớp trình bao bọc

def class_decorator[cls]:
   class WrapperClass:
       def __init__[self, *args, **kwargs]:
           self.instance = cls[*args, **kwargs]
       def __getattribute__[self, attrib]:
           try:
               obj = super[].__getattribute__[attrib]
               return obj
           except AttributeError:
               # will handle the situation below
               pass

           obj = self.instance.__getattribute__[attrib]
           return obj

Bên trong khối thử, chúng tôi đang cố gắng tìm thuộc tính trong phần tử gốc với sự trợ giúp của super call. Trong Python 3, bạn không cần phải truyền tên lớp cha và thể hiện hiện tại [tức là chính nó]

Nếu điều đó không được tìm thấy, chúng tôi sẽ cố gắng tìm thấy điều đó bên trong thể hiện của lớp mà chúng tôi sẽ trang trí

Nhưng không ổn nếu chỉ tìm thấy trong trường hợp. Chúng ta cũng nên tìm thấy nó bên trong lớp của thể hiện. Để làm như vậy, hãy sửa đổi mã của chúng tôi

def class_decorator[cls]:
   class WrapperClass:
       def __init__[self, *args, **kwargs]:
           self.instance = cls[*args, **kwargs]
       def __getattribute__[self, attrib]:
           try:
               obj = super[].__getattribute__[attrib]
               return obj
           except AttributeError:
               # will handle the situation below
               pass

           obj = self.instance.__getattribute__[attrib]
           if callable[obj]:
               return meth_decorator[obj]
           else:
               return obj

Chú ý hai dòng

if callable[obj]:
   return meth_decorator[obj]
else:
   return obj

getattribute[] không chỉ tìm thấy các phương thức, nó còn tìm thấy bất kỳ thuộc tính nào mà nó có thể tìm thấy. Vì vậy, chúng tôi cần kiểm tra xem đối tượng đó có thể gọi được hay không. Để đơn giản, chúng tôi chỉ giả sử rằng kiểm tra callable[] ở đây là đủ, mặc dù còn nhiều điều nữa

Vì vậy, mã cuối cùng của chúng ta sẽ giống như sau

def meth_decorator[method]:
   def method_wrapper[self, *args, **kwargs]:
       print[self.__class__.__name__ + "::" + method.__name__ + "[]:"]
       method[self, *args, **kwargs]
       print[]

   return method_wrapper

def class_decorator[cls]:
   class WrapperClass:
       def __init__[self, *args, **kwargs]:
           self.instance = cls[*args, **kwargs]
       def __getattribute__[self, attrib]:
           try:
               obj = super[].__getattribute__[attrib]
               return obj
           except AttributeError:
               # will handle the situation below
               pass

           obj = self.instance.__getattribute__[attrib]
           if callable[obj]:
               return meth_decorator[obj]
           else:
               return obj

   return WrapperClass


@class_decorator
class C:
   def say_hello[self, name]:
       print["Hello, %s" % name]

   def say_bye[self, name]:
       print["Bye, %s" % name]

   def say_go_fast[self, name]:
       print["Go fast, %s" % name]

c = C[]
c.say_hello["Sabuj"]
c.say_go_fast["Justt Arifin"]
c.say_bye["Sarker"]

Chạy nó để xem đầu ra sau

________số 8

Vậy là chúng ta đã có một method decorator khá hoàn hảo

Phần kết luận

Sử dụng các bộ trang trí rất dễ dàng và thú vị, nhưng việc tạo các bộ trang trí phức tạp thì không. Bạn cần tự mình thực hành tất cả các mã để hiểu nó và bạn nên nghĩ ra những ý tưởng mới để bạn có thể thử nghiệm những điều mới. Tôi hy vọng sẽ nghĩ ra những thứ phức tạp và nâng cao hơn liên quan đến trình trang trí trong Python trong tương lai. Tiếp tục mã hóa với Python

Chủ Đề