Tất cả các lớp này đều có sẵn trong mô-đun collections
và [thực tế là có tổng cộng 25 lớp] được định nghĩa trong mô-đun thư viện tiêu chuẩn trong _collections_abc.py
Có một số vấn đề ở đây mà tôi tin rằng làm cho _collections_abc.py
vượt trội hơn so với cấu trúc thư mục giả định thay thế
- Các tệp này được sắp xếp theo thứ tự bảng chữ cái. Bạn có thể sắp xếp chúng theo những cách khác, nhưng tôi không biết về tính năng sắp xếp tệp theo phụ thuộc ngữ nghĩa. Nguồn mô-đun _collections_abc được tổ chức theo sự phụ thuộc
- Trong các trường hợp không bệnh lý, cả định nghĩa mô-đun và lớp đều là đơn lẻ, xuất hiện một lần trong bộ nhớ. Sẽ có một ánh xạ phỏng đoán của các mô-đun lên các lớp - làm cho các mô-đun trở nên dư thừa
- Số lượng tệp ngày càng tăng khiến việc đọc qua các lớp không thuận tiện [trừ khi bạn có một IDE làm cho nó đơn giản] - khiến những người không có công cụ khó truy cập hơn
Bạn có bị ngăn cản việc chia các nhóm lớp thành các mô-đun khác nhau khi bạn thấy điều đó là mong muốn từ góc độ tổ chức và không gian tên không?
Không
Từ Zen of Python , phản ánh triết lý và nguyên tắc mà nó đã phát triển và phát triển
Không gian tên là một ý tưởng tuyệt vời -- hãy làm nhiều hơn thế nữa
Nhưng chúng ta hãy nhớ rằng nó cũng nói
Căn hộ tốt hơn lồng nhau
Python cực kỳ rõ ràng và dễ đọc. Nó khuyến khích bạn đọc nó. Đặt mỗi lớp riêng biệt trong một tệp riêng biệt không khuyến khích đọc. Điều này đi ngược lại triết lý cốt lõi của Python. Nhìn vào cấu trúc của Thư viện tiêu chuẩn, phần lớn các mô-đun là mô-đun tệp đơn, không phải gói. Tôi muốn trình bày với bạn rằng mã Python thành ngữ được viết theo cùng kiểu với lib tiêu chuẩn của CPython
Đây là mã thực tế từ mô-đun lớp cơ sở trừu tượng. Tôi thích sử dụng nó như một tài liệu tham khảo để biểu thị các loại trừu tượng khác nhau trong ngôn ngữ
Bạn có nói rằng mỗi lớp này nên yêu cầu một tệp riêng không?
class Hashable:
__metaclass__ = ABCMeta
@abstractmethod
def __hash__[self]:
return 0
@classmethod
def __subclasshook__[cls, C]:
if cls is Hashable:
try:
for B in C.__mro__:
if "__hash__" in B.__dict__:
if B.__dict__["__hash__"]:
return True
break
except AttributeError:
# Old-style class
if getattr[C, "__hash__", None]:
return True
return NotImplemented
class Iterable:
__metaclass__ = ABCMeta
@abstractmethod
def __iter__[self]:
while False:
yield None
@classmethod
def __subclasshook__[cls, C]:
if cls is Iterable:
if _hasattr[C, "__iter__"]:
return True
return NotImplemented
Iterable.register[str]
class Iterator[Iterable]:
@abstractmethod
def next[self]:
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration
def __iter__[self]:
return self
@classmethod
def __subclasshook__[cls, C]:
if cls is Iterator:
if _hasattr[C, "next"] and _hasattr[C, "__iter__"]:
return True
return NotImplemented
class Sized:
__metaclass__ = ABCMeta
@abstractmethod
def __len__[self]:
return 0
@classmethod
def __subclasshook__[cls, C]:
if cls is Sized:
if _hasattr[C, "__len__"]:
return True
return NotImplemented
class Container:
__metaclass__ = ABCMeta
@abstractmethod
def __contains__[self, x]:
return False
@classmethod
def __subclasshook__[cls, C]:
if cls is Container:
if _hasattr[C, "__contains__"]:
return True
return NotImplemented
class Callable:
__metaclass__ = ABCMeta
@abstractmethod
def __call__[self, *args, **kwds]:
return False
@classmethod
def __subclasshook__[cls, C]:
if cls is Callable:
if _hasattr[C, "__call__"]:
return True
return NotImplemented
Vì vậy, mỗi người nên có tập tin riêng của họ?
tôi hy vọng không
Các tệp này không chỉ là mã - chúng là tài liệu về ngữ nghĩa của Python
Chúng có thể trung bình từ 10 đến 20 dòng. Tại sao tôi phải vào một tệp hoàn toàn riêng biệt để xem 10 dòng mã khác? . Hơn nữa, sẽ có các bản nhập soạn sẵn gần như giống hệt nhau trên mỗi tệp, thêm nhiều dòng mã dự phòng hơn
Tôi thấy khá hữu ích khi biết rằng có một mô-đun duy nhất nơi tôi có thể tìm thấy tất cả các Lớp Cơ sở Trừu tượng này, thay vì phải xem qua danh sách các mô-đun. Xem chúng trong ngữ cảnh với nhau cho phép tôi hiểu rõ hơn về chúng. Khi tôi thấy một Iterator là một Iterable, tôi có thể nhanh chóng xem lại Iterable bao gồm những gì bằng cách liếc lên
Đôi khi tôi có một vài lớp học rất ngắn. Chúng ở trong tệp, ngay cả khi chúng cần phát triển lớn hơn theo thời gian. Đôi khi các mô-đun trưởng thành có hơn 1000 dòng mã. Nhưng ctrl-f rất dễ dàng và một số IDE giúp dễ dàng xem các đường viền của tệp - vì vậy, bất kể tệp lớn đến đâu, bạn có thể nhanh chóng chuyển đến bất kỳ đối tượng hoặc phương thức nào mà bạn đang tìm kiếm
Phần kết luận
Hướng của tôi, trong ngữ cảnh của Python, là thích giữ các định nghĩa lớp có liên quan và giống nhau về mặt ngữ nghĩa trong cùng một tệp. Nếu tệp phát triển quá lớn đến mức trở nên khó sử dụng, thì hãy xem xét tổ chức lại