Python 3 có hỗ trợ quá tải không?

PEP này đề xuất một mô-đun thư viện tiêu chuẩn mới,

@overload
def flatten[ob: MyString]:
    yield ob
7, để cung cấp các tính năng lập trình chung bao gồm nạp chồng động [còn gọi là các hàm chung], giao diện, thích ứng, kết hợp phương thức [ala CLOS và AspectJ] và các dạng lập trình hướng khía cạnh đơn giản [AOP]

API được đề xuất cũng được mở rộng; . và các tiện ích mở rộng đó sẽ được API đề xuất coi là công dân hạng nhất

API sẽ được triển khai bằng Python thuần túy không có C, nhưng có thể có một số phụ thuộc vào các tính năng dành riêng cho CPython, chẳng hạn như

@overload
def flatten[ob: MyString]:
    yield ob
8 và thuộc tính
@overload
def flatten[ob: MyString]:
    yield ob
9 của hàm. Dự kiến ​​là e. g. Jython và IronPython sẽ có những cách khác để triển khai chức năng tương tự [có thể sử dụng Java hoặc C#]

Python luôn cung cấp nhiều hàm chung trong thư viện tiêu chuẩn và tích hợp sẵn, chẳng hạn như

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
0,
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
1,
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
2 và hầu hết các hàm trong mô-đun
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
3. Tuy nhiên, nó hiện

  1. không có cách đơn giản hoặc dễ hiểu để các nhà phát triển tạo các chức năng chung mới,
  2. không có cách tiêu chuẩn để thêm các phương thức vào các hàm chung hiện có [i. e. , một số được thêm vào bằng cách sử dụng các chức năng đăng ký, một số khác yêu cầu xác định các phương thức
    from overloading import RuleSet
    RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
    
    4, có thể bằng cách ghép nối], và
  3. không cho phép gửi trên nhiều loại đối số [ngoại trừ ở dạng giới hạn cho các toán tử số học, trong đó các phương thức “tay phải” [
    from overloading import RuleSet
    RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
    
    5] có thể được sử dụng để thực hiện gửi hai đối số

Ngoài ra, hiện tại, mã Python là một mô hình chống phổ biến để kiểm tra các loại đối số nhận được, để quyết định phải làm gì với các đối tượng. Ví dụ, mã có thể muốn chấp nhận một đối tượng thuộc loại nào đó hoặc một chuỗi các đối tượng thuộc loại đó

Hiện tại, “cách hiển nhiên” để thực hiện việc này là kiểm tra kiểu loại, nhưng cách này dễ gãy và khó mở rộng. Nhà phát triển sử dụng thư viện đã viết sẵn có thể không thể thay đổi cách đối tượng của họ được xử lý bằng mã đó, đặc biệt nếu đối tượng họ đang sử dụng được tạo bởi bên thứ ba

Do đó, PEP này đề xuất một mô-đun thư viện tiêu chuẩn để giải quyết những vấn đề này và các vấn đề liên quan, sử dụng trình trang trí và chú thích đối số [PEP 3107]. Các tính năng chính được cung cấp là

  • một phương tiện nạp chồng động, tương tự như nạp chồng tĩnh có trong các ngôn ngữ như Java và C++, nhưng bao gồm các tính năng kết hợp phương thức tùy chọn như trong CLOS và AspectJ
  • một thư viện "giao diện và thích ứng" đơn giản lấy cảm hứng từ các lớp kiểu chữ của Haskell [nhưng năng động hơn và không có bất kỳ kiểm tra kiểu tĩnh nào], với API mở rộng để cho phép đăng ký các loại giao diện do người dùng xác định, chẳng hạn như các loại được tìm thấy trong PyProtocols và Zope
  • triển khai "khía cạnh" đơn giản để giúp dễ dàng tạo bộ điều hợp trạng thái và thực hiện AOP trạng thái khác

Các tính năng này sẽ được cung cấp theo cách có thể tạo và sử dụng các triển khai mở rộng. Ví dụ: các thư viện có thể xác định các tiêu chí điều phối mới cho các chức năng chung và các loại giao diện mới và sử dụng chúng thay cho các tính năng được xác định trước. Ví dụ: có thể sử dụng đối tượng giao diện

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
6 để chỉ định loại đối số hàm mong muốn, miễn là gói
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
6 đã tự đăng ký chính xác [hoặc bên thứ ba đã đăng ký]

Theo cách này, API được đề xuất chỉ cung cấp một cách thống nhất để truy cập chức năng trong phạm vi của nó, thay vì quy định một triển khai duy nhất được sử dụng cho tất cả các thư viện, khung và ứng dụng

Quá tải API sẽ được triển khai dưới dạng một mô-đun duy nhất, có tên là

@overload
def flatten[ob: MyString]:
    yield ob
7, cung cấp các tính năng sau

Trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
5 cho phép bạn xác định các triển khai thay thế của hàm, được chuyên biệt hóa theo [các] loại đối số. Một hàm có cùng tên phải tồn tại trong không gian tên cục bộ. Chức năng hiện có được trình trang trí sửa đổi tại chỗ để thêm triển khai mới và chức năng đã sửa đổi được trả về bởi trình trang trí. Vì vậy, đoạn mã sau

@overload
def flatten[ob: MyString]:
    yield ob
3

tạo một hàm

@overload
def flatten[ob: MyString]:
    yield ob
40 duy nhất có cách thực hiện tương đương với

@overload
def flatten[ob: MyString]:
    yield ob
5

ngoại trừ chức năng

@overload
def flatten[ob: MyString]:
    yield ob
40 được xác định bằng quá tải vẫn mở để mở rộng bằng cách thêm nhiều quá tải hơn, trong khi phiên bản được mã hóa cứng không thể được mở rộng

Ví dụ: nếu ai đó muốn sử dụng

@overload
def flatten[ob: MyString]:
    yield ob
40 với kiểu giống như chuỗi không phân lớp
@overload
def flatten[ob: MyString]:
    yield ob
43, thì họ sẽ không may mắn với cách triển khai thứ hai. Tuy nhiên, với việc triển khai quá tải, họ có thể viết điều này

@overload
def flatten[ob: MyString]:
    yield ob

hoặc cái này [để tránh sao chép việc thực hiện]

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]

[Cũng lưu ý rằng, mặc dù PEP 3119 đề xuất rằng các lớp cơ sở trừu tượng như

@overload
def flatten[ob: MyString]:
    yield ob
44 có thể cho phép các lớp như
@overload
def flatten[ob: MyString]:
    yield ob
45 yêu cầu lớp con, yêu cầu như vậy là toàn cầu, xuyên suốt ứng dụng. Ngược lại, việc thêm quá tải cụ thể hoặc sao chép quy tắc là dành riêng cho một chức năng riêng lẻ và do đó ít có khả năng gây ra tác dụng phụ không mong muốn. ]

Trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
5 là cách viết tắt trường hợp phổ biến cho trình trang trí
@overload
def flatten[ob: MyString]:
    yield ob
6 tổng quát hơn. Nó cho phép bạn loại bỏ tên của hàm mà bạn đang quá tải, với chi phí yêu cầu hàm đích nằm trong không gian tên cục bộ. Nó cũng không hỗ trợ thêm các tiêu chí bổ sung bên cạnh các tiêu chí được chỉ định thông qua chú thích đối số. Các định nghĩa hàm sau đây có tác dụng giống hệt nhau, ngoại trừ tác dụng phụ ràng buộc tên [sẽ được mô tả bên dưới]

@overload
def flatten[ob: MyString]:
    yield ob
4

Định nghĩa đầu tiên ở trên sẽ ràng buộc

@overload
def flatten[ob: MyString]:
    yield ob
60 với bất kỳ thứ gì trước đó nó bị ràng buộc. Đối số thứ hai sẽ làm tương tự, nếu nó đã được liên kết với đối số đầu tiên của trình trang trí
@overload
def flatten[ob: MyString]:
    yield ob
61. Nếu
@overload
def flatten[ob: MyString]:
    yield ob
60 không bị ràng buộc hoặc bị ràng buộc với thứ gì khác, thì nó sẽ được phục hồi về định nghĩa hàm như đã cho. Hai định nghĩa cuối cùng ở trên sẽ luôn ràng buộc
@overload
def flatten[ob: MyString]:
    yield ob
63 với định nghĩa hàm như đã cho

Sử dụng cách tiếp cận này cho phép bạn vừa đặt tên mô tả cho phương thức [thường hữu ích trong truy nguyên. ] và để sử dụng lại phương thức sau này

Trừ khi có quy định khác, tất cả các nhà trang trí

@overload
def flatten[ob: MyString]:
    yield ob
7 đều có cùng chữ ký và các quy tắc ràng buộc như
@overload
def flatten[ob: MyString]:
    yield ob
6. Họ chấp nhận một chức năng và một đối tượng "vị ngữ" tùy chọn

Việc triển khai vị từ mặc định là một bộ các loại có khớp vị trí với các đối số của hàm bị quá tải. Tuy nhiên, có thể tạo và đăng ký một số lượng tùy ý các loại vị ngữ khác bằng cách sử dụng , sau đó sẽ có thể sử dụng được với

@overload
def flatten[ob: MyString]:
    yield ob
6 và các bộ trang trí khác được tạo bởi mô-đun này [như
@overload
def flatten[ob: MyString]:
    yield ob
67,
@overload
def flatten[ob: MyString]:
    yield ob
68 và
@overload
def flatten[ob: MyString]:
    yield ob
69]

Khi một chức năng quá tải được gọi, việc triển khai có chữ ký khớp cụ thể nhất với các đối số gọi là đối số được sử dụng. Nếu không có triển khai nào phù hợp, lỗi

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
60 sẽ xuất hiện. Nếu có nhiều hơn một triển khai phù hợp, nhưng không có chữ ký nào cụ thể hơn những chữ ký khác, lỗi
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
61 sẽ xuất hiện

Ví dụ: cặp triển khai sau đây là không rõ ràng, nếu hàm

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
62 đã từng được gọi với hai đối số nguyên, bởi vì cả hai chữ ký sẽ được áp dụng, nhưng không có chữ ký nào cụ thể hơn chữ ký kia [i. e. , cái này không hàm ý cái kia]

@overload
def flatten[ob: MyString]:
    yield ob
6

Ngược lại, cặp triển khai sau đây không bao giờ có thể mơ hồ, bởi vì chữ ký này luôn bao hàm chữ ký kia;

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
6

Chữ ký S1 ngụ ý một chữ ký khác S2, nếu bất cứ khi nào S1 được áp dụng, S2 cũng sẽ. Chữ ký S1 “cụ thể hơn” so với chữ ký S2 khác, nếu S1 ngụ ý S2, nhưng S2 không ngụ ý S1

Mặc dù các ví dụ trên đều đã sử dụng các kiểu cụ thể hoặc trừu tượng làm chú thích đối số, nhưng không có yêu cầu rằng các chú thích phải như vậy. Chúng cũng có thể là các đối tượng “giao diện” [được thảo luận trong phần này], bao gồm các loại giao diện do người dùng định nghĩa. [Chúng cũng có thể là các đối tượng khác có loại được đăng ký thích hợp thông qua. ]

Nếu tham số đầu tiên của một hàm bị quá tải có tên là

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65, nó sẽ được truyền một hàm có thể gọi được đại diện cho phương thức cụ thể nhất tiếp theo. Ví dụ, mã này

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
4

Sẽ in “có số nguyên. ” theo sau là “có đồ vật. ”

Nếu không có phương thức cụ thể nhất tiếp theo, thì

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 sẽ bị ràng buộc với một phiên bản
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
60. Khi được gọi, một phiên bản
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
60 mới sẽ được nâng lên, với các đối số được truyền cho phiên bản đầu tiên

Tương tự, nếu các phương thức cụ thể nhất tiếp theo có mức độ ưu tiên không rõ ràng đối với nhau, thì

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 sẽ được liên kết với một phiên bản
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
61 và nếu được gọi, nó sẽ tạo ra một phiên bản mới

Do đó, một phương thức có thể kiểm tra xem

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 có phải là một trường hợp lỗi hay không hoặc chỉ cần gọi nó. Các lớp lỗi
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
60 và
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
61 có một lớp cơ sở chung là
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
44, vì vậy
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
45 là đủ để xác định liệu có thể gọi một cách an toàn
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 hay không

[Ghi chú thực hiện. sử dụng một tên đối số ma thuật như

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 có thể được thay thế bằng một hàm ma thuật sẽ được gọi để lấy phương thức tiếp theo. Tuy nhiên, một chức năng ma thuật sẽ làm giảm hiệu suất và có thể khó triển khai hơn trên các nền tảng không phải CPython. Tuy nhiên, việc xâu chuỗi phương thức thông qua các tên đối số ma thuật có thể được triển khai hiệu quả trên bất kỳ nền tảng Python nào hỗ trợ tạo các phương thức liên kết từ các hàm – một cách đơn giản là liên kết đệ quy từng hàm để được xâu chuỗi, sử dụng hàm hoặc lỗi sau đây làm
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
48 của phương thức liên kết. ]

Ngoài chuỗi phương thức tiếp theo đơn giản được hiển thị ở trên, đôi khi rất hữu ích khi có các cách kết hợp phương thức khác. Ví dụ: "mẫu người quan sát" đôi khi có thể được triển khai bằng cách thêm các phương thức bổ sung vào một chức năng, thực thi trước hoặc sau khi triển khai thông thường

Để hỗ trợ các trường hợp sử dụng này, mô-đun

@overload
def flatten[ob: MyString]:
    yield ob
7 sẽ cung cấp các bộ trang trí
@overload
def flatten[ob: MyString]:
    yield ob
67,
@overload
def flatten[ob: MyString]:
    yield ob
68 và
@overload
def flatten[ob: MyString]:
    yield ob
69, gần tương ứng với các loại phương thức giống nhau trong Hệ thống đối tượng Lisp chung [CLOS] hoặc các loại “lời khuyên” tương ứng trong AspectJ

Giống như

@overload
def flatten[ob: MyString]:
    yield ob
6, tất cả các bộ trang trí này phải được truyền chức năng bị quá tải và cũng có thể tùy ý chấp nhận một vị ngữ

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
3

Các phương thức

@overload
def flatten[ob: MyString]:
    yield ob
67 và
@overload
def flatten[ob: MyString]:
    yield ob
68 được gọi trước hoặc sau thân hàm chính và không bao giờ được coi là mơ hồ. Tức là sẽ không gây ra bất kỳ lỗi nào khi có nhiều phương thức “trước” hoặc “sau” có chữ ký trùng hoặc trùng nhau. Sự mơ hồ được giải quyết bằng cách sử dụng thứ tự các phương thức được thêm vào hàm đích

Các phương thức "Trước" được gọi phương thức cụ thể nhất trước tiên, với các phương thức không rõ ràng được thực thi theo thứ tự chúng được thêm vào. Tất cả các phương thức "trước" được gọi trước bất kỳ phương thức "chính" nào của hàm [i. e. các phương thức

@overload
def flatten[ob: MyString]:
    yield ob
5 bình thường] được thực thi

Các phương thức "Sau" được gọi theo thứ tự ngược lại, sau khi tất cả các phương thức "chính" của hàm được thực thi. Nghĩa là, chúng được thực thi các phương thức ít cụ thể nhất trước tiên, với các phương thức không rõ ràng được thực thi ngược lại với thứ tự mà chúng được thêm vào

Các giá trị trả về của cả hai phương thức “trước” và “sau” đều bị bỏ qua và mọi ngoại lệ chưa được phát hiện do bất kỳ phương thức nào [chính hoặc khác] đưa ra sẽ ngay lập tức kết thúc quá trình gửi. Các phương thức “Trước” và “sau” không thể có đối số

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65, vì chúng không chịu trách nhiệm gọi bất kỳ phương thức nào khác. Chúng được gọi đơn giản như một thông báo trước hoặc sau các phương thức chính

Do đó, các phương pháp “trước” và “sau” có thể được sử dụng để kiểm tra hoặc thiết lập các điều kiện tiên quyết [e. g. bằng cách đưa ra lỗi nếu điều kiện không được đáp ứng] hoặc để đảm bảo hậu điều kiện mà không cần sao chép bất kỳ chức năng hiện có nào

Trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
69 khai báo một phương thức là một phương thức “xung quanh”. Các phương thức “xung quanh” giống như các phương thức chính, ngoại trừ phương thức “xung quanh” ít cụ thể nhất có mức độ ưu tiên cao hơn so với phương thức “trước” cụ thể nhất

Tuy nhiên, không giống như các phương thức “before” và “after”, các phương thức “Around” chịu trách nhiệm gọi đối số

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 của chúng để tiếp tục quá trình gọi. Các phương thức “Xung quanh” thường được sử dụng để chuyển đổi các đối số đầu vào hoặc giá trị trả về hoặc để bao bọc các trường hợp cụ thể với xử lý lỗi đặc biệt hoặc điều kiện thử/cuối cùng, v.v. g

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
0

Chúng cũng có thể được sử dụng để thay thế cách xử lý thông thường cho một trường hợp cụ thể, bằng cách không gọi hàm

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 được cung cấp cho một phương thức “xung quanh” sẽ là phương thức “xung quanh” có thể áp dụng tiếp theo, một thể hiện của
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
44 hoặc một đối tượng phương thức tổng hợp sẽ gọi tất cả các phương thức “trước”, tiếp theo là chuỗi phương thức chính, tiếp theo là tất cả các

Do đó, giống như với các phương thức thông thường, có thể kiểm tra

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65 để tìm
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
44-ness hoặc đơn giản là gọi. Phương thức “xung quanh” sẽ trả về giá trị được trả về bởi
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65, tất nhiên trừ khi nó muốn sửa đổi hoặc thay thế nó bằng một giá trị trả về khác cho toàn bộ hàm

Các bộ trang trí được mô tả ở trên [

@overload
def flatten[ob: MyString]:
    yield ob
5,
@overload
def flatten[ob: MyString]:
    yield ob
6,
@overload
def flatten[ob: MyString]:
    yield ob
67,
@overload
def flatten[ob: MyString]:
    yield ob
68 và
@overload
def flatten[ob: MyString]:
    yield ob
69] cùng nhau triển khai những gì trong CLOS được gọi là “sự kết hợp phương pháp tiêu chuẩn” – các mẫu phổ biến nhất được sử dụng trong các phương pháp kết hợp

Tuy nhiên, đôi khi, một ứng dụng hoặc thư viện có thể được sử dụng cho một kiểu kết hợp phương thức phức tạp hơn. Ví dụ: nếu bạn muốn có các phương thức "giảm giá" trả về phần trăm giảm giá, được trừ vào giá trị được trả về bởi [các] phương thức chính, bạn có thể viết một cái gì đó như thế này

@overload
def flatten[ob: MyString]:
    yield ob
50

Các kỹ thuật tương tự có thể được sử dụng để triển khai nhiều quy tắc kết hợp và hạn định phương thức kiểu CLOS. Quá trình tạo các đối tượng kết hợp phương thức tùy chỉnh và các bộ trang trí tương ứng của chúng được mô tả chi tiết hơn trong phần

Nhân tiện, xin lưu ý rằng trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
501 được hiển thị sẽ hoạt động chính xác với bất kỳ vị từ mới nào được xác định bởi mã khác. Ví dụ: nếu
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
6 đăng ký các loại giao diện của nó để hoạt động chính xác dưới dạng chú thích đối số, bạn sẽ có thể chỉ định chiết khấu trên cơ sở các loại giao diện của nó, không chỉ các lớp hoặc loại giao diện do
@overload
def flatten[ob: MyString]:
    yield ob
7 xác định

Tương tự, nếu một thư viện như RuleDispatch hoặc PEAK-Rules đăng ký một công cụ gửi và triển khai vị từ thích hợp, thì người ta cũng có thể sử dụng các vị từ đó để giảm giá, ví dụ:. g

@overload
def flatten[ob: MyString]:
    yield ob
51

Quá trình xác định các loại vị từ tùy chỉnh và công cụ điều phối cũng được mô tả chi tiết hơn trong phần

Tất cả các bộ trang trí ở trên đều có một hành vi bổ sung đặc biệt khi chúng được gọi trực tiếp trong thân lớp. tham số đầu tiên [không phải là

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
65, nếu có] của hàm được trang trí sẽ được xử lý như thể nó có một chú thích tương đương với lớp mà nó được định nghĩa

Đó là, mã này

@overload
def flatten[ob: MyString]:
    yield ob
52

tạo ra hiệu ứng tương tự như thế này [ngoài sự tồn tại của một phương thức riêng tư]

@overload
def flatten[ob: MyString]:
    yield ob
53

Hành vi này vừa là một cải tiến thuận tiện khi xác định nhiều phương thức, vừa là một yêu cầu để phân biệt an toàn các quá tải đa đối số trong các lớp con. Ví dụ, xem xét đoạn mã sau

@overload
def flatten[ob: MyString]:
    yield ob
54

Do quy tắc lớp ẩn, việc gọi

@overload
def flatten[ob: MyString]:
    yield ob
505 sẽ in ra “B got an iterable. ” theo sau là “nó có thể lặp lại. ”, và cuối cùng, “got an object”, trong khi
@overload
def flatten[ob: MyString]:
    yield ob
506 sẽ chỉ in các thông báo được xác định trong
@overload
def flatten[ob: MyString]:
    yield ob
507

Ngược lại, nếu không có quy tắc lớp ngầm định, hai phương thức “Có thể lặp lại” sẽ có các điều kiện áp dụng hoàn toàn giống nhau, do đó, việc gọi

@overload
def flatten[ob: MyString]:
    yield ob
506 hoặc
@overload
def flatten[ob: MyString]:
    yield ob
505 sẽ dẫn đến lỗi
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
61

Hiện tại đây là một vấn đề mở để xác định cách tốt nhất để triển khai quy tắc này trong Python 3. 0. Theo Python 2. x, siêu dữ liệu của một lớp không được chọn cho đến khi kết thúc phần thân của lớp, điều đó có nghĩa là người trang trí có thể chèn một siêu dữ liệu tùy chỉnh để thực hiện xử lý loại này. [Ví dụ, đây là cách RuleDispatch triển khai quy tắc lớp ẩn. ]

Tuy nhiên, PEP 3115 yêu cầu siêu dữ liệu của lớp phải được xác định trước khi phần thân lớp thực thi, khiến không thể sử dụng kỹ thuật này để trang trí lớp nữa

Tại bài viết này, cuộc thảo luận về vấn đề này đang diễn ra

Mô-đun

@overload
def flatten[ob: MyString]:
    yield ob
7 cung cấp triển khai đơn giản các giao diện và khả năng thích ứng. Ví dụ sau định nghĩa một giao diện
@overload
def flatten[ob: MyString]:
    yield ob
512 và tuyên bố rằng các đối tượng
@overload
def flatten[ob: MyString]:
    yield ob
513 hỗ trợ nó

@overload
def flatten[ob: MyString]:
    yield ob
55

Lớp

@overload
def flatten[ob: MyString]:
    yield ob
514 là một loại “bộ chuyển đổi vạn năng”. Nó chấp nhận một đối số duy nhất. một đối tượng để thích nghi. Sau đó, nó liên kết tất cả các phương thức của nó với đối tượng đích, thay cho chính nó. Do đó, gọi
@overload
def flatten[ob: MyString]:
    yield ob
515] cũng giống như gọi
@overload
def flatten[ob: MyString]:
    yield ob
516

Trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
517 đánh dấu một chức năng là trừu tượng. tôi. e. , không có triển khai. Nếu một hàm
@overload
def flatten[ob: MyString]:
    yield ob
517 được gọi, nó sẽ tăng
from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
60. Để có thể thực thi được, các phương thức quá tải phải được thêm vào bằng cách sử dụng các kỹ thuật được mô tả trước đó. [Nghĩa là, các phương thức có thể được thêm vào bằng cách sử dụng
@overload
def flatten[ob: MyString]:
    yield ob
6,
@overload
def flatten[ob: MyString]:
    yield ob
67,
@overload
def flatten[ob: MyString]:
    yield ob
68,
@overload
def flatten[ob: MyString]:
    yield ob
69 hoặc bất kỳ trình trang trí kết hợp phương thức tùy chỉnh nào. ]

Trong ví dụ trên, phương thức

@overload
def flatten[ob: MyString]:
    yield ob
524 được thêm vào như một phương thức cho
@overload
def flatten[ob: MyString]:
    yield ob
525 khi các đối số của nó là một danh sách và một đối tượng tùy ý. Do đó,
@overload
def flatten[ob: MyString]:
    yield ob
516 được dịch sang
@overload
def flatten[ob: MyString]:
    yield ob
527, do đó thực hiện thao tác mong muốn

Nhân tiện, xin lưu ý rằng trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
517 không bị giới hạn sử dụng trong các định nghĩa giao diện; . Đặc biệt, nó không cần phải được sử dụng bên trong một lớp

Cũng lưu ý rằng các phương thức giao diện không cần phải trừu tượng;

@overload
def flatten[ob: MyString]:
    yield ob
56

Miễn là

@overload
def flatten[ob: MyString]:
    yield ob
529 được xác định cho một số loại, giao diện trên sẽ cung cấp triển khai
@overload
def flatten[ob: MyString]:
    yield ob
530 có thể sử dụng được. Tuy nhiên, nếu một số loại cụ thể [hoặc cặp loại] có cách xử lý hiệu quả hơn các hoạt động của
@overload
def flatten[ob: MyString]:
    yield ob
530, thì vẫn có thể đăng ký quá tải thích hợp để sử dụng trong trường hợp đó

Giao diện có thể được phân lớp

@overload
def flatten[ob: MyString]:
    yield ob
57

Hoặc được lắp ráp bằng cách kết hợp các chức năng từ các giao diện hiện có

@overload
def flatten[ob: MyString]:
    yield ob
58

Một lớp có thể được coi là “thích ứng với” một giao diện tại một thời điểm nhất định, nếu không có phương thức nào được xác định trong giao diện được đảm bảo sẽ gây ra lỗi

from overloading import RuleSet
RuleSet[flatten].copy_rules[[basestring,], [MyString,]]
60 nếu được gọi trên một phiên bản của lớp đó tại thời điểm đó

Tuy nhiên, trong cách sử dụng thông thường, “xin tha thứ dễ hơn xin phép”. Nghĩa là, việc sử dụng một giao diện trên một đối tượng sẽ dễ dàng hơn bằng cách thích ứng nó với giao diện [e. g.

@overload
def flatten[ob: MyString]:
    yield ob
533] hoặc gọi trực tiếp các phương thức giao diện [e. g.
@overload
def flatten[ob: MyString]:
    yield ob
516], hơn là cố gắng tìm hiểu xem đối tượng có thể thích ứng với [hoặc triển khai trực tiếp] giao diện hay không

Có thể khai báo rằng một lớp trực tiếp cài đặt một giao diện, sử dụng hàm

@overload
def flatten[ob: MyString]:
    yield ob
535

@overload
def flatten[ob: MyString]:
    yield ob
59

Cuộc gọi

@overload
def flatten[ob: MyString]:
    yield ob
535 ở trên gần tương đương với các bước sau

@overload
def flatten[ob: MyString]:
    yield ob
0

Nghĩa là, gọi

@overload
def flatten[ob: MyString]:
    yield ob
525 hoặc
@overload
def flatten[ob: MyString]:
    yield ob
538 trên một thể hiện của bất kỳ lớp con nào của
@overload
def flatten[ob: MyString]:
    yield ob
539, sẽ chỉ ủy quyền cho các phương thức thực tế của
@overload
def flatten[ob: MyString]:
    yield ob
540 hoặc
@overload
def flatten[ob: MyString]:
    yield ob
541 của chúng

Vì mục đích hiệu quả, gọi

@overload
def flatten[ob: MyString]:
    yield ob
542 trong đó
@overload
def flatten[ob: MyString]:
    yield ob
543 là phiên bản của
@overload
def flatten[ob: MyString]:
    yield ob
539, có thể trả về
@overload
def flatten[ob: MyString]:
    yield ob
543 thay vì bộ điều hợp
@overload
def flatten[ob: MyString]:
    yield ob
512. [Lưu ý rằng việc gọi
@overload
def flatten[ob: MyString]:
    yield ob
547 trong đó
@overload
def flatten[ob: MyString]:
    yield ob
548 đã là bộ điều hợp
@overload
def flatten[ob: MyString]:
    yield ob
512 sẽ luôn trả về
@overload
def flatten[ob: MyString]:
    yield ob
548 không thay đổi; đây là một tối ưu hóa bổ sung được phép trong trường hợp người nhận điều chỉnh được biết là trực tiếp triển khai giao diện mà không cần điều chỉnh. ]

Để thuận tiện, có thể hữu ích khi khai báo các triển khai trong tiêu đề lớp, e. g

@overload
def flatten[ob: MyString]:
    yield ob
1

Thay vì gọi

@overload
def flatten[ob: MyString]:
    yield ob
535 sau khi kết thúc bộ

Các lớp con

@overload
def flatten[ob: MyString]:
    yield ob
514 có thể được sử dụng làm chú thích đối số để chỉ ra loại đối tượng nào có thể chấp nhận được khi quá tải, e. g

@overload
def flatten[ob: MyString]:
    yield ob
2

Tuy nhiên, lưu ý rằng các đối số thực tế không bị thay đổi hoặc điều chỉnh theo bất kỳ cách nào chỉ bằng cách sử dụng một giao diện làm chỉ định loại. Bạn phải chuyển các đối tượng sang giao diện thích hợp một cách rõ ràng, như được hiển thị ở trên

Tuy nhiên, lưu ý rằng có thể có các kiểu sử dụng giao diện khác. Ví dụ: các triển khai giao diện khác có thể không hỗ trợ thích ứng hoặc có thể yêu cầu các đối số chức năng đã được điều chỉnh phù hợp với giao diện đã chỉ định. Vì vậy, ngữ nghĩa chính xác của việc sử dụng một giao diện làm công cụ xác định kiểu phụ thuộc vào các đối tượng giao diện mà bạn thực sự sử dụng

Tuy nhiên, đối với các đối tượng giao diện được xác định bởi PEP này, ngữ nghĩa như được mô tả ở trên. Giao diện I1 được coi là "cụ thể hơn" so với giao diện I2 khác, nếu tập hợp các bộ mô tả trong hệ thống phân cấp thừa kế của I1 là tập hợp thay thế thích hợp của các bộ mô tả trong hệ thống phân cấp thừa kế của I2

Vì vậy, ví dụ,

@overload
def flatten[ob: MyString]:
    yield ob
553 cụ thể hơn cả
@overload
def flatten[ob: MyString]:
    yield ob
554 và
@overload
def flatten[ob: MyString]:
    yield ob
553, bất kể mối quan hệ thừa kế giữa các giao diện này. Đó hoàn toàn là câu hỏi về những hoạt động nào được bao gồm trong các giao diện đó – và tên của các hoạt động không quan trọng

Các giao diện [ít nhất là những giao diện được cung cấp bởi

@overload
def flatten[ob: MyString]:
    yield ob
7] luôn được coi là ít cụ thể hơn so với các lớp cụ thể. Các triển khai giao diện khác có thể quyết định các quy tắc cụ thể của riêng chúng, cả giữa giao diện và giao diện khác và giữa giao diện và lớp

Việc triển khai

@overload
def flatten[ob: MyString]:
    yield ob
514 thực sự xử lý tất cả các thuộc tính và phương thức [i. e. mô tả] theo cùng một cách. các phương thức
@overload
def flatten[ob: MyString]:
    yield ob
558 [và
@overload
def flatten[ob: MyString]:
    yield ob
559 và
@overload
def flatten[ob: MyString]:
    yield ob
560, nếu có] của chúng được gọi với đối tượng được bao bọc [được điều chỉnh] là “self”. Đối với các chức năng, điều này có tác dụng tạo ra một phương thức ràng buộc liên kết chức năng chung với đối tượng được bao bọc

Đối với các thuộc tính không có chức năng, có thể dễ dàng nhất để chỉ định chúng bằng cách sử dụng các thuộc tính tích hợp sẵn

@overload
def flatten[ob: MyString]:
    yield ob
561 và các thuộc tính
@overload
def flatten[ob: MyString]:
    yield ob
562,
@overload
def flatten[ob: MyString]:
    yield ob
563 và
@overload
def flatten[ob: MyString]:
    yield ob
564 tương ứng

@overload
def flatten[ob: MyString]:
    yield ob
3

Ngoài ra, các phương thức như

@overload
def flatten[ob: MyString]:
    yield ob
565 và
@overload
def flatten[ob: MyString]:
    yield ob
566 có thể được định nghĩa là một phần của giao diện và thuộc tính được xác định theo các phương thức đó, nhưng điều này khó hơn một chút đối với người dùng để triển khai chính xác khi tạo một lớp trực tiếp triển khai giao diện, như

Hệ thống thích ứng được mô tả ở trên giả định rằng các bộ điều hợp là “không trạng thái”, nghĩa là các bộ điều hợp không có thuộc tính hoặc trạng thái nào khác với đối tượng được điều chỉnh. Điều này tuân theo mô hình “typeclass/instance” của Haskell và khái niệm “thuần túy” [i. e. , có thể kết hợp chuyển tiếp] bộ điều hợp

Tuy nhiên, đôi khi có những trường hợp, để cung cấp triển khai hoàn chỉnh một số giao diện, cần phải có một số loại trạng thái bổ sung.

Tất nhiên, một khả năng có thể là đính kèm các thuộc tính “riêng tư” của Monkeypatch vào bộ điều hợp. Nhưng điều này có thể gây xung đột tên và làm phức tạp quá trình khởi tạo [vì bất kỳ mã nào sử dụng các thuộc tính này đều phải kiểm tra sự tồn tại của chúng và khởi tạo chúng nếu cần]. Nó cũng không hoạt động trên các đối tượng không có thuộc tính

@overload
def flatten[ob: MyString]:
    yield ob
567

Vì vậy, lớp

@overload
def flatten[ob: MyString]:
    yield ob
568 được cung cấp để dễ dàng đính kèm thông tin bổ sung vào các đối tượng mà một trong hai

  1. có thuộc tính
    @overload
    def flatten[ob: MyString]:
        yield ob
    
    567 [vì vậy các thể hiện khía cạnh có thể được lưu trữ trong đó, được khóa bởi lớp khía cạnh],
  2. hỗ trợ tham chiếu yếu [vì vậy các phiên bản khía cạnh có thể được quản lý bằng cách sử dụng từ điển tham chiếu yếu toàn cầu nhưng an toàn cho luồng] hoặc
  3. triển khai hoặc có thể thích ứng với giao diện
    @overload
    def flatten[ob: MyString]:
        yield ob
    
    570 [về mặt kỹ thuật, #1 hoặc #2 ngụ ý điều này]

Phân lớp

@overload
def flatten[ob: MyString]:
    yield ob
568 tạo ra một lớp bộ điều hợp có trạng thái gắn liền với vòng đời của đối tượng được điều chỉnh

Ví dụ: giả sử bạn muốn đếm tất cả số lần một phương thức nhất định được gọi trong các phiên bản của

@overload
def flatten[ob: MyString]:
    yield ob
572 [một ví dụ AOP cổ điển]. Bạn có thể làm một cái gì đó như

@overload
def flatten[ob: MyString]:
    yield ob
4

Đoạn mã trên sẽ theo dõi số lần mà

@overload
def flatten[ob: MyString]:
    yield ob
573 được gọi thành công trên một phiên bản của
@overload
def flatten[ob: MyString]:
    yield ob
572 [i. e. , nó sẽ không tính lỗi trừ khi chúng xảy ra trong một phương thức "sau" cụ thể hơn]. Sau đó, mã khác có thể truy cập số đếm bằng cách sử dụng
@overload
def flatten[ob: MyString]:
    yield ob
575

Tất nhiên, các phiên bản

@overload
def flatten[ob: MyString]:
    yield ob
568 có thể có các phương thức
@overload
def flatten[ob: MyString]:
    yield ob
577, để khởi tạo bất kỳ cấu trúc dữ liệu nào. Họ có thể sử dụng các thuộc tính dựa trên từ điển hoặc
@overload
def flatten[ob: MyString]:
    yield ob
578 để lưu trữ

Mặc dù cơ sở này khá thô sơ so với một công cụ AOP đầy đủ tính năng như AspectJ, nhưng những người muốn xây dựng thư viện pointcut hoặc các tính năng giống AspectJ khác chắc chắn có thể sử dụng các đối tượng

@overload
def flatten[ob: MyString]:
    yield ob
568 và trình trang trí kết hợp phương thức làm cơ sở để xây dựng các công cụ AOP biểu cảm hơn

XXX chỉ định API khía cạnh đầy đủ, bao gồm các khóa, khía cạnh N-to-1, đính kèm/tách/xóa các phiên bản khía cạnh theo cách thủ công và giao diện
@overload
def flatten[ob: MyString]:
    yield ob
580

LÀM. giải thích làm thế nào tất cả những điều này làm việc

ngụ ý [o1, o2]

khai báo_thực hiện [iface, lớp]

predicate_signatures[ob]

parse_rule[ruleset, body, predicate, actiontype, localdict, globaldict]

tổ hợp_hành động[a1, a2]

quy tắc_cho[f]

đối tượng quy tắc

đối tượng ActionDef

đối tượng RuleSet

đối tượng phương thức

đối tượng MethodList

Chủ sở hữu IAspect

Trong cuộc thảo luận về danh sách Python-3000, tính năng được đề xuất cho phép quá tải các hàm tùy ý đã gây tranh cãi phần nào, với một số người bày tỏ lo ngại rằng điều này sẽ khiến chương trình trở nên khó hiểu hơn.

Lực đẩy chung của lập luận này là người ta không thể dựa vào chức năng của một chức năng, nếu nó có thể được thay đổi từ bất kỳ đâu trong chương trình vào bất kỳ lúc nào. Mặc dù về nguyên tắc, điều này đã có thể xảy ra thông qua sửa lỗi hoặc thay thế mã, nhưng việc làm như vậy được coi là thực hành kém

Tuy nhiên, việc cung cấp hỗ trợ cho quá tải bất kỳ chức năng nào [hay còn gọi là tranh luận], hoàn toàn ủng hộ những thay đổi như vậy là một thông lệ có thể chấp nhận được

Lập luận này dường như có ý nghĩa về mặt lý thuyết, nhưng nó gần như hoàn toàn được đưa ra tranh luận trong thực tế vì hai lý do.

Đầu tiên, mọi người thường không biến thái, xác định một chức năng để làm một việc ở một nơi, và sau đó xác định tóm tắt nó để làm điều ngược lại ở một nơi khác. Những lý do chính để mở rộng hành vi của một chức năng chưa được tạo ra cụ thể là để

  • Thêm các trường hợp đặc biệt mà tác giả của chức năng ban đầu không dự tính, chẳng hạn như hỗ trợ cho các loại bổ sung
  • Được thông báo về một hành động để thực hiện một số hoạt động liên quan, trước khi hoạt động ban đầu được thực hiện, sau đó hoặc cả hai. Điều này có thể bao gồm các hoạt động có mục đích chung như thêm ghi nhật ký, thời gian hoặc theo dõi, cũng như hành vi dành riêng cho ứng dụng

Tuy nhiên, không có lý do nào trong số những lý do thêm quá tải này hàm ý bất kỳ thay đổi nào đối với hành vi tổng thể hoặc mặc định dự định của chức năng hiện có, tuy nhiên. Giống như một phương thức của lớp cơ sở có thể bị ghi đè bởi một lớp con vì hai lý do tương tự, do đó, một chức năng cũng có thể bị quá tải để cung cấp cho những cải tiến đó

Nói cách khác, quá tải phổ quát không đồng nghĩa với quá tải tùy ý, theo nghĩa là chúng ta không cần mong đợi mọi người xác định lại một cách ngẫu nhiên hành vi của các chức năng hiện có theo những cách phi logic hoặc không thể đoán trước. Nếu họ làm như vậy, đó sẽ là một cách làm tồi tệ không kém bất kỳ cách viết mã phi logic hoặc không thể đoán trước nào khác.

Tuy nhiên, để phân biệt thực hành xấu với tốt, có lẽ cần phải làm rõ thêm thực tiễn tốt để xác định quá tải là gì. Và điều đó đưa chúng ta đến lý do thứ hai tại sao các hàm chung không nhất thiết làm cho chương trình khó hiểu hơn. các mẫu quá tải trong các chương trình thực tế có xu hướng tuân theo các mẫu rất dễ đoán. [Cả bằng Python và các ngôn ngữ không có chức năng không chung chung. ]

Nếu một mô-đun đang xác định một hoạt động chung mới, nó thường cũng sẽ xác định bất kỳ tình trạng quá tải bắt buộc nào đối với các loại hiện có ở cùng một vị trí. Tương tự như vậy, nếu một mô-đun đang xác định một loại mới, thì nó thường sẽ xác định tình trạng quá tải ở đó cho bất kỳ chức năng chung nào mà nó biết hoặc quan tâm.

Do đó, phần lớn các tình trạng quá tải có thể được tìm thấy bên cạnh chức năng đang bị quá tải hoặc với một loại mới được xác định mà tình trạng quá tải đang thêm hỗ trợ. Do đó, tình trạng quá tải rất dễ bị phát hiện trong trường hợp phổ biến, khi bạn đang xem xét chức năng hoặc loại hoặc cả hai

Chỉ trong những trường hợp khá hiếm gặp, người ta mới có quá tải trong một mô-đun không chứa chức năng cũng như [các] loại mà quá tải được thêm vào. Điều này sẽ xảy ra nếu, giả sử, bên thứ ba tạo cầu nối hỗ trợ giữa các loại của thư viện này và [các] chức năng chung của thư viện khác. Tuy nhiên, trong trường hợp như vậy, cách tốt nhất là nên quảng cáo điều này một cách nổi bật, đặc biệt là bằng tên mô-đun

Ví dụ: PyProtocols xác định hỗ trợ cầu nối như vậy để làm việc với các giao diện Zope và giao diện Twisted kế thừa, sử dụng các mô-đun có tên là

@overload
def flatten[ob: MyString]:
    yield ob
581 và
@overload
def flatten[ob: MyString]:
    yield ob
582. [Những cây cầu này được thực hiện với bộ điều hợp giao diện, thay vì các chức năng chung, nhưng nguyên tắc cơ bản là giống nhau. ]

Nói tóm lại, việc hiểu các chương trình khi có quá tải phổ quát không còn khó khăn nữa, vì phần lớn các tình trạng quá tải sẽ liền kề với một hàm hoặc định nghĩa về loại được truyền cho hàm đó

Và, trong trường hợp không có sự thiếu năng lực hoặc cố ý làm mờ, một số tình trạng quá tải không liền kề với [các] loại hoặc [các] chức năng có liên quan, nói chung sẽ không cần phải hiểu hoặc biết về bên ngoài phạm vi mà những tình trạng quá tải đó . [Ngoại trừ trong trường hợp "mô-đun hỗ trợ", nơi thực hành tốt nhất đề nghị đặt tên cho chúng phù hợp. ]

Hầu hết các chức năng được mô tả trong PEP này đã được triển khai trong phiên bản đang phát triển của khung Quy tắc PEAK. Đặc biệt, khung kết hợp phương thức và nạp chồng cơ bản [trừ trình trang trí

@overload
def flatten[ob: MyString]:
    yield ob
5] đã tồn tại ở đó. Việc triển khai tất cả các tính năng này trong
@overload
def flatten[ob: MyString]:
    yield ob
584 là 656 dòng Python khi viết bài này

@overload
def flatten[ob: MyString]:
    yield ob
584 hiện dựa trên các mô-đun DecoratorTools và BytecodeAssembler, nhưng cả hai phần phụ thuộc này đều có thể được thay thế, vì DecoratorTools được sử dụng chủ yếu cho Python 2. 3 và để triển khai các loại cấu trúc [có thể được thực hiện với các bộ dữ liệu được đặt tên trong các phiên bản Python sau này]. Việc sử dụng Bytecode Assembler có thể được thay thế bằng cách sử dụng giải pháp thay thế "điều hành" hoặc "biên dịch", với nỗ lực hợp lý. [Sẽ dễ dàng hơn để làm điều này nếu thuộc tính
@overload
def flatten[ob: MyString]:
    yield ob
586 của các đối tượng hàm có thể ghi được. ]

Lớp

@overload
def flatten[ob: MyString]:
    yield ob
514 đã được tạo nguyên mẫu trước đây, nhưng không được bao gồm trong Quy tắc PEAK tại thời điểm hiện tại

"Quy tắc lớp ẩn" trước đây đã được triển khai trong thư viện RuleDispatch. Tuy nhiên, nó dựa vào móc

@overload
def flatten[ob: MyString]:
    yield ob
588 hiện đã bị loại bỏ trong PEP 3115

Tôi hiện không biết làm thế nào để làm cho

@overload
def flatten[ob: MyString]:
    yield ob
5 chơi tốt với
@overload
def flatten[ob: MyString]:
    yield ob
590 và
@overload
def flatten[ob: MyString]:
    yield ob
591 trong các cơ quan lớp học. Nó không thực sự rõ ràng nếu nó cần, tuy nhiên

Python 3 có hỗ trợ nạp chồng hàm không?

Python không hỗ trợ nạp chồng hàm như các ngôn ngữ khác và tham số hàm không có kiểu dữ liệu.

Tại sao Python không hỗ trợ quá tải?

Chỉ có thể có một. Bởi vì python không thực sự hỗ trợ nhập các tham số hàm, nên thực sự không thể xác định "hàm" nào sẽ được sử dụng dựa trên các loại đối số được truyền

Python có hỗ trợ quá tải và ghi đè không?

Python không hỗ trợ nạp chồng phương thức . Ghi đè phương thức là định nghĩa lại một phương thức của lớp cha trong lớp dẫn xuất. Ghi đè yêu cầu kế thừa để thực hiện.

Tại sao Python không hỗ trợ quá tải hàm tạo?

Nếu hàm tạo được viết hai lần với các chữ ký khác nhau, chúng ta gọi quá tải hàm tạo. Khái niệm nạp chồng phương thức và nạp chồng hàm tạo có thể có trong các ngôn ngữ khác như java và c++. Trong hàm tạo và phương thức python, không thể nạp chồng .

Chủ Đề