Khi nào tôi nên sử dụng python lớp trừu tượng?

Các lớp trừu tượng là gì? . Đến cuối bài đăng này, bạn sẽ hiểu rõ về ABC trong Python và cách thêm chúng vào chương trình của bạn

Hãy bắt đầu nào

Mã của chúng tôi không có lớp trừu tượng

Tôi tin rằng cách tốt nhất để tìm hiểu là với một ví dụ, vì vậy hãy xem đoạn mã sau

class Lion:
    def give_food(self):
        print("Feeding a lion with raw meat!")

class Panda:
    def feed_animal(self):
        print("Feeding a panda with some tasty bamboo!")

class Snake:
    def feed_snake(self):
        print("Feeding a snake with mice!")

# Animals of our zoo:
leo = Lion()
po = Panda()
sam = Snake()

Công việc của chúng tôi là cho tất cả các loài động vật ăn bằng tập lệnh Python. Một cách để làm điều đó sẽ là

leo.give_food()
po.feed_animal()
sam.feed_snake()

Điều này sẽ làm việc. Nhưng hãy tưởng tượng sẽ mất bao nhiêu thời gian để làm điều này cho mỗi con vật trong một sở thú lớn, lặp đi lặp lại cùng một quy trình và mã hàng trăm lần. Điều đó cũng sẽ làm cho mã khó bảo trì hơn

Hiện tại cấu trúc chương trình của chúng tôi trông giống như thế này

Chúng tôi muốn tối ưu hóa quy trình, vì vậy chúng tôi có thể đưa ra giải pháp như thế này

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!

Vấn đề là mỗi lớp có một tên phương thức khác nhau, khi cho sư tử ăn nó là

leo.give_food()
po.feed_animal()
sam.feed_snake()
5, khi cho gấu trúc ăn là
leo.give_food()
po.feed_animal()
sam.feed_snake()
6 và nó là
leo.give_food()
po.feed_animal()
sam.feed_snake()
7 cho rắn

Mã này là một mớ hỗn độn vì các phương thức thực hiện cùng một việc nên được đặt tên giống nhau

Nếu chúng ta chỉ có thể buộc các lớp của mình triển khai cùng tên phương thức

Giới thiệu các lớp Trừu tượng

Hóa ra lớp Trừu tượng là thứ chúng ta cần. Về cơ bản, nó buộc các lớp con của nó thực hiện tất cả các phương thức trừu tượng của nó. Nó là một lớp đại diện cho các lớp con của nó trông như thế nào

Một cấu trúc tốt hơn có thể trông như thế này (______1_______8 là một lớp Trừu tượng)

Bằng cách giới thiệu một lớp trừu tượng (

leo.give_food()
po.feed_animal()
sam.feed_snake()
8), mọi lớp kế thừa từ
leo.give_food()
po.feed_animal()
sam.feed_snake()
8 phải triển khai các phương thức trừu tượng từ
leo.give_food()
po.feed_animal()
sam.feed_snake()
8, trong trường hợp của chúng ta là phương thức
# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
2

Chúng ta hãy xem mã

from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass

Khi định nghĩa một lớp trừu tượng, chúng ta cần kế thừa từ Lớp cơ sở trừu tượng -

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
3

Để định nghĩa một phương thức trừu tượng trong lớp trừu tượng, chúng ta phải sử dụng một trình trang trí.

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
4. Mô-đun
# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
5 tích hợp chứa cả hai

Nếu bạn kế thừa từ lớp Animal nhưng không triển khai các phương thức trừu tượng, bạn sẽ gặp lỗi

class Panda(Animal): # If a class inherits from an ABC, it must implement all it's abstract methods!
    def wrong_name(self): # The method's name must match the name of the ABC's method
        print("Feeding a panda with some tasty bamboo!")

Nếu chúng ta cố gắng khởi tạo lớp (e. g.

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
6 ) nó sẽ ném ra một
# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
7 vì chúng ta không thể khởi tạo Panda mà không có một phương thức trừu tượng
# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
2

Hãy ghi nhớ điều đó, chúng ta cần tạo ra những con vật của mình (lần này là chính xác)

class Lion(Animal):
    def feed(self):
        print("Feeding a lion with raw meat!") 

class Panda(Animal): 
    def feed(self): 
        print("Feeding a panda with some tasty bamboo!") 

class Snake(Animal): 
    def feed(self): 
        print("Feeding a snake with mice!")

Và cuối cùng, đây là tất cả mã chúng ta cần để tạo và cho động vật ăn

zoo = [Lion(), Panda(), Snake()]

for animal in zoo:
    animal.feed() # Now this won't throw an error!

Viết các phương thức trừu tượng với các tham số

Điều gì xảy ra khi một phương thức trừu tượng có tham số? . Việc triển khai của lớp con cũng có thể thêm các tham số bổ sung nếu cần

from abc import ABC,abstractmethod 

class Animal(ABC):
    @abstractmethod  
    def do(self, action): # Renamed it to "do", and it has "action" parameter
        pass

class Lion(Animal): 
    def do(self, action, time): # It's still mandatory to implement action. "time" is our other parameter
        print(f"{action} a lion! At {time}") 

class Panda(Animal): 
    def do(self, action, time): 
        print(f"{action} a panda! At {time}") 

class Snake(Animal): 
    def do(self, action, time): 
        print(f"{action} a snake! At {time}")
zoo = [Lion(), Panda(), Snake()]

for animal in zoo:
    animal.do(action="feeding", time="10:10 PM")

Chạy đoạn mã trên sẽ in ra

feeding a lion! At 10:10 PM
feeding a panda! At 10:10 PM
feeding a snake! At 10:10 PM

Chúng tôi cũng có thể sử dụng các đối số mặc định, bạn có thể đọc về những đối số đó

Thuộc tính viết (trừu tượng)

Chúng tôi cũng có thể muốn tạo các thuộc tính trừu tượng và buộc lớp con của chúng tôi triển khai các thuộc tính đó. Điều này có thể được thực hiện bằng cách sử dụng trang trí

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
9 cùng với
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
0

Vì động vật thường có chế độ ăn khác nhau nên chúng ta sẽ cần xác định một

from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
1 trong các lớp động vật của chúng ta. Vì tất cả các loài động vật đều được thừa hưởng từ
leo.give_food()
po.feed_animal()
sam.feed_snake()
8, nên chúng ta có thể định nghĩa
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
1 là một tài sản trừu tượng. Bên cạnh
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
1, chúng tôi sẽ tạo tài sản
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
5 và nó là
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
6 sẽ kiểm tra xem chúng tôi có đang cố cho con vật ăn thứ gì đó không có trên đó là
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
1

Hãy xem mã của

leo.give_food()
po.feed_animal()
sam.feed_snake()
8,
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
9 và
class Panda(Animal): # If a class inherits from an ABC, it must implement all it's abstract methods!
    def wrong_name(self): # The method's name must match the name of the ABC's method
        print("Feeding a panda with some tasty bamboo!")
0

leo.give_food()
po.feed_animal()
sam.feed_snake()
0

Chúng ta có thể tạo hai đối tượng, đặt thức ăn mà chúng ta sẽ cho chúng ăn và sau đó gọi phương thức

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
2

leo.give_food()
po.feed_animal()
sam.feed_snake()
1

Điều đó sẽ in ra

leo.give_food()
po.feed_animal()
sam.feed_snake()
2

Nếu chúng ta cố gắng cho một con vật ăn thứ gì đó mà nó không ăn

leo.give_food()
po.feed_animal()
sam.feed_snake()
3

from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
6 sẽ tăng
class Panda(Animal): # If a class inherits from an ABC, it must implement all it's abstract methods!
    def wrong_name(self): # The method's name must match the name of the ABC's method
        print("Feeding a panda with some tasty bamboo!")
3

leo.give_food()
po.feed_animal()
sam.feed_snake()
4

Một từ trên lớp Meta trừu tượng

Bạn có thể đã bắt gặp siêu dữ liệu khi tìm hiểu về các lớp trừu tượng

Một lớp định nghĩa cách một thể hiện của lớp hành xử (e. g.

leo.give_food()
po.feed_animal()
sam.feed_snake()
8 mô tả cách
from abc import ABC, abstractmethod
# abc is a builtin module, we have to import ABC and abstractmethod

class Animal(ABC): # Inherit from ABC(Abstract base class)
    @abstractmethod  # Decorator to define an abstract method
    def feed(self):
        pass
9 sẽ cư xử). Mặt khác, siêu dữ liệu xác định cách hoạt động của một lớp (
class Panda(Animal): # If a class inherits from an ABC, it must implement all it's abstract methods!
    def wrong_name(self): # The method's name must match the name of the ABC's method
        print("Feeding a panda with some tasty bamboo!")
6 mô tả cách mọi lớp
# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
3 sẽ hoạt động). Một lớp là một thể hiện của một siêu dữ liệu

Mô-đun

# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
5 đi kèm với siêu dữ liệu
class Panda(Animal): # If a class inherits from an ABC, it must implement all it's abstract methods!
    def wrong_name(self): # The method's name must match the name of the ABC's method
        print("Feeding a panda with some tasty bamboo!")
6. trở lại những ngày chúng tôi phải sử dụng nó để xác định siêu dữ liệu với
class Lion(Animal):
    def feed(self):
        print("Feeding a lion with raw meat!") 

class Panda(Animal): 
    def feed(self): 
        print("Feeding a panda with some tasty bamboo!") 

class Snake(Animal): 
    def feed(self): 
        print("Feeding a snake with mice!")
0
Ngày nay, chỉ kế thừa từ
# Put all the animals in a list:
zoo = [leo, po, sam] # Could be many more animals there!

# Loop through the animals and feed them
for animal in zoo:
	# But what do we put here now?
	# Is it animal.give_food() or animal.feed_animal(), hmm?
	animal.feed() # This will throw an AttributeError!
3 cũng làm được điều tương tự—vì vậy bạn hoàn toàn không phải lo lắng về siêu dữ liệu

Tóm lược

Trong bài đăng trên blog này, chúng tôi đã mô tả những điều cơ bản về các lớp trừu tượng của Python. Chúng đặc biệt hữu ích khi làm việc theo nhóm với các nhà phát triển khác và các phần của dự án được phát triển song song

Dưới đây là một số điểm chính

  • Các lớp trừu tượng đảm bảo rằng các lớp dẫn xuất triển khai các phương thức và thuộc tính được định nghĩa trong lớp cơ sở trừu tượng
  • Lớp cơ sở trừu tượng không thể được khởi tạo
  • Chúng tôi sử dụng
    # Put all the animals in a list:
    zoo = [leo, po, sam] # Could be many more animals there!
    
    # Loop through the animals and feed them
    for animal in zoo:
    	# But what do we put here now?
    	# Is it animal.give_food() or animal.feed_animal(), hmm?
    	animal.feed() # This will throw an AttributeError!
    
    4 để định nghĩa một phương thức trong lớp cơ sở trừu tượng và kết hợp giữa
    # Put all the animals in a list:
    zoo = [leo, po, sam] # Could be many more animals there!
    
    # Loop through the animals and feed them
    for animal in zoo:
    	# But what do we put here now?
    	# Is it animal.give_food() or animal.feed_animal(), hmm?
    	animal.feed() # This will throw an AttributeError!
    
    9 và
    # Put all the animals in a list:
    zoo = [leo, po, sam] # Could be many more animals there!
    
    # Loop through the animals and feed them
    for animal in zoo:
    	# But what do we put here now?
    	# Is it animal.give_food() or animal.feed_animal(), hmm?
    	animal.feed() # This will throw an AttributeError!
    
    4 để định nghĩa một thuộc tính trừu tượng

Tôi hy vọng bạn đã học được một cái gì đó mới ngày hôm nay. Nếu bạn đang muốn nâng cấp kỹ năng Python của mình hơn nữa, hãy xem Khóa học Python hoàn chỉnh của chúng tôi

Khi nào bạn nên sử dụng một lớp trừu tượng?

Một lớp trừu tượng được sử dụng nếu bạn muốn cung cấp chức năng chung, được triển khai trong số tất cả các triển khai của thành phần . Các lớp trừu tượng sẽ cho phép bạn triển khai một phần lớp của mình, trong khi các giao diện sẽ không triển khai cho bất kỳ thành viên nào.

Tại sao nên sử dụng lớp trừu tượng trong Python?

Trong Python, các lớp cơ sở trừu tượng cung cấp bản thiết kế cho các lớp cụ thể . Chúng không chứa triển khai. Thay vào đó, chúng cung cấp một giao diện và đảm bảo rằng các lớp cụ thể dẫn xuất được triển khai đúng cách. Các lớp cơ sở trừu tượng không thể được khởi tạo.

Tại sao và khi nào chúng ta nên sử dụng một lớp trừu tượng?

Một lớp trừu tượng là một lựa chọn tốt nếu bạn có kế hoạch mở rộng trong tương lai – i. e. nếu có khả năng mở rộng trong tương lai trong hệ thống phân cấp lớp. Nếu bạn muốn cung cấp hỗ trợ cho việc mở rộng trong tương lai khi sử dụng giao diện, bạn sẽ cần mở rộng giao diện và tạo một giao diện mới.