Tham gia của Python dường như không tập trung vào các mục để tham gia, mà là biểu tượng, so với Ruby hoặc Smalltalk, vì lý do thiết kế?


9

Tôi nghĩ một trong những nền tảng của OOP là, chúng tôi có các đối tượng, đó là những mục chúng tôi quan tâm để xử lý, và sau đó chúng tôi gửi tin nhắn cho họ.

Vì vậy, có vẻ tự nhiên rằng, tôi có một bộ sưu tập các mặt hàng và tôi cần đặt chúng vào một chuỗi, để làm điều đó:

  ["x", "o", "o"].join(" | ")    # joining a tic-tac-toe row in Ruby

(Smalltalk làm theo cách tương tự). Theo " | "một cách nào đó, nó được coi là một đối số, một mã thông báo về cách tham gia nó. Nó có thể là " "quá, nếu bảng trò chơi là đơn giản hơn. Vì vậy, yếu tố tham gia " | "không phải là thứ chúng tôi quan tâm đặc biệt - nó không phải là đối tượng chính trong chương trình có tầm quan trọng hoặc ý nghĩa đặc biệt.

Nếu Python sử dụng nó

  " | ".join(["x", "o", "o"])

Nó cảm thấy hơi kỳ lạ khi nó gần như cảm thấy như chúng ta đang gửi một thông điệp đến đối số, để nói với đối số về điều gì đó. Có lẽ Python là thủ tục hơn? Để nói với chuỗi tham gia để thực hiện một số nhiệm vụ cho chúng tôi?

Có phải để lưu thực hiện, để chúng ta không phải xác định một joincho mỗi lớp bộ sưu tập chúng ta có? Nhưng không phải là chúng ta cũng có thể viết một lần cho bất kỳ lớp sưu tập nào, chẳng hạn như trong Ruby:

module Enumerable
  def my_join(joiner)
    self.inject {|a,b| a.to_s + joiner + b.to_s}
  end
end

(một cái gì đó như thế này, kêu gọi to_stừng mục, dựa vào to_stừng lớp để làm điều đúng đắn của riêng nó, để chuyển đổi thành một chuỗi, và sau đó nối chúng lại). Vì vậy, sau đó chúng ta không phải triển khai cho từng Chuỗi, Hash hoặc Set hoặc bất kỳ lớp bộ sưu tập nào chúng ta có.

Hay Python ra ngoài không đi theo con đường OOP? Nó sử dụng len("abc")type([])thay vì "abc".len()hoặc [].type()thậm chí trong Python3. Python có làm theo cách này vì lý do thiết kế không?


7
Từ Zen của Python : "Nên có một-- và tốt nhất là chỉ có một cách rõ ràng để làm điều đó. Mặc dù cách đó có thể không rõ ràng lúc đầu trừ khi bạn là người Hà Lan."
kdgregory

2
Trong một hình thức, bộ sưu tập biết cách tự chuyển đổi thành một chuỗi bằng một dấu phân cách, trong một chuỗi khác biết cách ghép nối một bộ sưu tập bằng cách sử dụng chính nó như một dấu phân cách. Cả hai đều hướng đối tượng, nhưng thay đổi chủ đề và đối tượng của động từ.
kdgregory

Maybe Python is more procedural?Python là ngôn ngữ thủ tục với một vài bổ sung chức năng ("Python thu được lambda, less (), filter () và map (), nhờ một hacker Lisp đã bỏ lỡ chúng và gửi các bản vá hoạt động") cho đến khi có vẻ như ở đâu đó trong phiên bản 2. Đó là khoảng một thập kỷ rưỡi sau khi nó được làm việc lần đầu tiên.

1
Và ngay cả ngày nay Python thậm chí không cố gắng trở thành một ngôn ngữ OOP, nó hoàn toàn đa mô hình.

Giống như C ++, Python là ngôn ngữ cho phép OOP. Đây không giống như một ngôn ngữ OOP như Java hoặc Smalltalk.
Gort Robot

Câu trả lời:


9

Tham gia của Python được thiết kế để hoạt động trên bất kỳ lần lặp nào . Điều này có nghĩa là các nhà thiết kế đã phải quyết định nơi để đặt nó. Vì nó hoạt động trên nhiều danh sách, nhưng luôn yêu cầu (dấu phân cách) và trả về một chuỗi, nên chúng quyết định biến nó thành một phần của kiểu chuỗi.

Armin Ronacher nói điều đó tốt hơn tôi:

http://lucumr.pocoo.org/2011/7/9/python-and-pola/#seemingly-inverse-logic

"Hãy tưởng tượng Python sẽ không hoạt động theo cách đó. Trước tiên, bạn sẽ phải chuyển đổi iterable thành một danh sách thực tế để chuyển đổi nó thành một chuỗi. Giờ đây, Ruby sẽ tranh luận rằng Ruby giải quyết vấn đề này bằng cách trộn các mô-đun, và họ chắc chắn đúng rằng Tuy nhiên, đây là một quyết định thiết kế khó hiểu trong ngôn ngữ có nhiều hàm ý. Python khuyến khích khớp nối lỏng lẻo bằng cách có các giao thức này trong đó các triển khai thực tế có thể ở nơi khác. Một đối tượng có thể lặp lại, một phần khác trong hệ thống biết cách thực hiện thành một chuỗi. "


1
OP loại cố gắng giải quyết vấn đề này với module Enumeratephần nhưng Python không hoạt động theo cách đó, không có siêu lớp duy nhất cho tất cả các trình lặp mà bạn có thể đặt phương thức này.

Tôi cũng đã thử trong Ruby 2.0 ... HashStringthực sự không có lớp sưu tập nào như siêu lớp ... siêu lớp của chúng là như vậy Object. Vì vậy, hai lớp này chỉ dựa vào việc có Mixin vô số ... thứ gì đó mà tôi hiểu giống như một giao diện để cho phép tập hợp các hành vi của một bộ sưu tập
phân cực

Vì vậy, nó có khá nhiều hạn chế của thực tế là "iterable" không phải là một lớp hoặc một cái gì đó với mã thực tế, mà là một kiểu gõ vịt? Ngoài ra, đó đơn giản là vì Python muốn rất chung chung để có thể làm việc trên bất kỳ bộ sưu tập nào có cùng cách triển khai (trong khi nhiều thư viện tiêu chuẩn khác sẽ chỉ triển khai nó cho mỗi bộ sưu tập nếu nó thực sự áp dụng cho bộ sưu tập đó).
Kat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.