Nhược điểm của Python là gì? [đóng cửa]


147

Python dường như tất cả các cơn thịnh nộ ngày nay, và không đáng lo ngại - vì nó thực sự là một ngôn ngữ mà người ta gần như thích được đưa ra một vấn đề mới để giải quyết. Nhưng, như một người khôn ngoan đã từng nói (gọi anh ta là một người khôn ngoan chỉ bởi vì tôi không biết ai thực sự nói điều đó; không chắc anh ta có khôn ngoan không), để thực sự biết một ngôn ngữ mà người ta không chỉ biết nó cú pháp, thiết kế, vv, ưu điểm nhưng cũng có nhược điểm của nó. Không có ngôn ngữ nào là hoàn hảo, một số chỉ tốt hơn những ngôn ngữ khác.

Vì vậy, những gì sẽ là theo ý kiến ​​của bạn, nhược điểm khách quan của Python.

Lưu ý: Tôi không yêu cầu so sánh ngôn ngữ ở đây (ví dụ C # tốt hơn Python vì ... yadda yadda yadda) - nhiều ý kiến ​​khách quan (ở một mức độ nào đó) các tính năng ngôn ngữ được thiết kế tồi, cho dù, có thể là gì một số bạn đang thiếu trong đó và như vậy. Nếu phải sử dụng ngôn ngữ khác để so sánh, nhưng chỉ để minh họa một điểm khó có thể giải thích bằng cách khác (ví dụ để dễ hiểu)


50
Tôi nghĩ rằng đây là một câu hỏi chủ quan hữu ích, và sẽ thật xấu hổ khi đóng nó.
Eric Wilson

25
Dường như có một người hâm mộ trăn ở đây, người chỉ đánh giá thấp tất cả các câu trả lời chống trăn.
zvrba

2
@TMN: Điều đó vẫn coi khoảng trắng là mã thông báo, chỉ không trả lại chúng - và đó chính xác là những gì ngữ pháp của Python cũng làm.

9
@Roger: quy ước về SO là bình luận downvotes. Vì đây là một trang web cho ý kiến chủ quan , tôi thấy không có lý do gì để downvote, đặc biệt. w / o ý kiến. Vì vậy, tôi đứng bên "cách gọi tên" của mình.
zvrba

8
@zvrba: Downvotes vẫn có nghĩa là "không hữu ích", như mọi khi.

Câu trả lời:


109

Tôi sử dụng Python một cách thường xuyên và nói chung tôi coi đó là một ngôn ngữ rất tốt. Tuy nhiên, không có ngôn ngữ là hoàn hảo. Dưới đây là những hạn chế theo thứ tự quan trọng đối với cá nhân tôi:

  1. Nó chậm. Ý tôi là thực sự, rất chậm. Rất nhiều lần điều này không thành vấn đề, nhưng nó chắc chắn có nghĩa là bạn sẽ cần một ngôn ngữ khác cho các bit quan trọng về hiệu năng.

  2. Các hàm lồng nhau loại mà bạn không thể sửa đổi các biến trong phạm vi bên ngoài. Chỉnh sửa: Tôi vẫn sử dụng Python 2 do hỗ trợ thư viện và lỗi thiết kế này gây khó chịu cho tôi, nhưng rõ ràng nó đã được sửa trong Python 3 do câu lệnh không nhắm mục tiêu . Không thể chờ đợi các lib tôi sử dụng được chuyển để lỗ hổng này có thể được gửi đến đống tro tàn của lịch sử.

  3. Nó thiếu một vài tính năng có thể hữu ích cho thư viện / mã chung và IMHO là sự đơn giản được đưa đến các thái cực không lành mạnh. Các loại quan trọng nhất tôi có thể nghĩ đến là các loại giá trị do người dùng xác định (Tôi đoán chúng có thể được tạo bằng ma thuật siêu dữ liệu, nhưng tôi chưa bao giờ thử) và tham số hàm ref.

  4. Nó cách xa kim loại. Cần phải viết nguyên thủy luồng hoặc mã hạt nhân hoặc một cái gì đó? Chúc may mắn.

  5. Mặc dù tôi không bận tâm đến việc thiếu khả năng bắt lỗi ngữ nghĩa như một sự đánh đổi cho tính năng động mà Python đưa ra, tôi ước có một cách để bắt lỗi cú pháp và những thứ ngớ ngẩn như nhập nhầm tên biến mà không cần phải chạy mã.

  6. Tài liệu này không tốt bằng các ngôn ngữ như PHP và Java có sự hỗ trợ mạnh mẽ của công ty.


60
@Casey, tôi phải không đồng ý. Chỉ số này thật kinh khủng - hãy thử tra cứu withtuyên bố hoặc phương pháp trên a list. Bất cứ điều gì được đề cập trong hướng dẫn về cơ bản là không thể tìm kiếm. Tôi có nhiều may mắn hơn với tài liệu của Microsoft về C ++.
Đánh dấu tiền chuộc

17
Khoảng 5 - chỉ cần sử dụng pyflakes. Nó được viết để nắm bắt chính xác những lỗi đó.
Alexander Solovyov

4
Về tốc độ: với sự phát triển của PyPy, giờ đây nhiều người dùng Python sẽ có thể xử lý vấn đề tốc độ chỉ bằng cách sử dụng trình thông dịch có trình biên dịch JIT tích hợp (hiện tại, người dùng Python 3 và người dùng mô-đun mở rộng C không được xử lý bởi cpyext không có tùy chọn này).
ncoghlan

29
Tôi coi thường các tài liệu Python. Chúng chắc chắn hơn hầu hết chắc chắn, nhưng nhiều lần nhiều thông tin hữu ích được gộp vào một trang, như các phương thức trên chuỗi và danh sách - và tất cả các loại trình tự cũng được gộp lại với nhau. Khi tôi tìm kiếm thông tin này, tôi chỉ tìm thấy một cuốn sách lớn và phải tìm kiếm trên trang để tìm những gì tôi muốn. Tôi cũng thấy chỉ mục trên các trang này khó đọc và đôi khi rất khó để biết phần nào tôi muốn.
Carson Myers

5
Làm thế nào có thể khoảng cách từ kim loại là một đối số? Python có bao giờ tự coi mình là ngôn ngữ hệ thống không?
Đánh dấu Canlas

66

Tôi ghét rằng Python không thể phân biệt giữa khai báo và sử dụng một biến. Bạn không cần gõ tĩnh để thực hiện điều đó. Thật tuyệt khi có một cách để nói rằng đây là một biến mà tôi cố tình khai báo và tôi có ý định giới thiệu một tên mới, đây không phải là một lỗi đánh máy.

Hơn nữa, tôi thường sử dụng các biến Python theo kiểu ghi một lần, nghĩa là tôi coi các biến là bất biến và không sửa đổi chúng sau lần gán đầu tiên. Nhờ các tính năng như hiểu danh sách, điều này thực sự dễ dàng đến không ngờ và làm cho dòng mã dễ theo dõi hơn.

Tuy nhiên, tôi không thể ghi lại sự thật đó. Không có gì trong Python ngăn tôi hình thành ghi đè hoặc sử dụng lại các biến.

Tóm lại, tôi muốn có hai từ khóa trong ngôn ngữ: varlet. Nếu tôi viết vào một biến không được khai báo bởi một trong hai biến đó, Python sẽ phát sinh lỗi. Hơn nữa, letkhai báo các biến là chỉ đọc, trong khi varcác biến là loại bình thường.

Xem xét ví dụ này:

x = 42    # Error: Variable `x` undeclared

var x = 1 # OK: Declares `x` and assigns a value.
x = 42    # OK: `x` is declared and mutable.

var x = 2 # Error: Redeclaration of existing variable `x`

let y     # Error: Declaration of read-only variable `y` without value
let y = 5 # OK: Declares `y` as read-only and assigns a value.

y = 23    # Error: Variable `y` is read-only

Lưu ý rằng các loại vẫn còn ẩn (nhưng letcác biến dành cho tất cả các ý định và mục đích được nhập tĩnh vì chúng không thể được bật lại thành một giá trị mới, trong khi varcác biến vẫn có thể được nhập động).

Cuối cùng, tất cả các đối số phương thức sẽ tự động là let, tức là chúng phải ở chế độ chỉ đọc. Nói chung không có lý do chính đáng để sửa đổi một tham số, ngoại trừ thành ngữ sau:

def foo(bar = None):
    if bar == None: bar = [1, 2, 3]

Điều này có thể được thay thế bằng một thành ngữ hơi khác:

def foo(bar = None):
    let mybar = bar or [1, 2, 3]

6
Tôi rất mong muốn Python có một câu lệnh "var". Bên cạnh lý do (rất tốt) mà bạn nêu, nó cũng sẽ giúp việc đọc mã dễ dàng hơn rất nhiều vì sau đó bạn có thể chỉ cần quét qua trang để phát hiện tất cả các khai báo biến.
jhocking

25
Như thể các nhà phát triển python bỏ qua các bài học trong quá khứ. Không khai báo biến, không khai báo hàm, là một sai lầm đầu tiên được thực hiện vào những năm 1950. Những lỗi khó tìm thấy do lỗi đánh máy khó phát hiện đã đủ đáng kinh ngạc lần đầu tiên được thực hiện vào những năm 1950. Lỗi ngôn ngữ này đã được thực hiện (và sau đó sửa chữa) hết lần này đến lần khác. Khai báo các biến không phải là một gánh nặng lớn. Nó đã cứu mông tôi nhiều lần. Tôi chắc chắn use strict;use warnings;perl trên một kịch bản có kích thước bất kỳ. Python đã tước đi nhà phát triển của quá nhiều công cụ gỡ lỗi.
David Hammen

19
@David, Để công bằng với python, nó sẽ đưa ra một ngoại lệ nếu bạn cố truy cập vào một biến chưa được gán. Nhiều ngôn ngữ thiếu khai báo sẽ trả về một số loại giá trị mặc định. Kết quả là phiên bản của Python ít gặp vấn đề hơn những phiên bản đó.
Winston Ewert

1
@yi_H Đề xuất không có nghĩa là tương thích ngược - hoặc thậm chí là một đề xuất thực sự. Câu hỏi đặt ra là, những nhược điểm của Python Mạnh Hồi là gì, không có varlet(hoặc một cơ chế tương tự) là một nhược điểm. Nói cách khác: nếu tôi là người thiết kế Python, tôi sẽ làm một cái gì đó như thế này. Điều đó nói rằng , các phiên bản trong tương lai có thể bao gồm điều này khi bạn tải một gói đặc biệt (tương tự __future__). Nói import strict. Tuy nhiên, điều này sẽ không xảy ra, vì nó đòi hỏi phải có cú pháp cú pháp
Konrad Rudolph

3
+1 Để thêm các khả năng lập trình 'giống như chức năng' tốt hơn.
Evan Plaice

44

Khiếu nại chính của tôi là phân luồng, không hoạt động trong nhiều trường hợp (so với Java, C và các vấn đề khác) do khóa trình thông dịch toàn cầu (xem bài nói chuyện "Bên trong Python GIL" (liên kết PDF) )

Tuy nhiên, có một giao diện đa xử lý rất dễ sử dụng, tuy nhiên nó sẽ nặng hơn về việc sử dụng bộ nhớ cho cùng một số tiến trình so với các luồng hoặc khó khăn nếu bạn có nhiều dữ liệu được chia sẻ. Tuy nhiên, lợi ích là một khi bạn có một chương trình làm việc với nhiều quy trình, nó có thể mở rộng trên nhiều máy, điều mà một chương trình luồng không thể làm được.

Tôi thực sự không đồng ý với những lời phê bình về tài liệu này, tôi nghĩ nó rất xuất sắc và tốt hơn hầu hết nếu không phải tất cả các ngôn ngữ chính ngoài kia.

Ngoài ra, bạn có thể bắt gặp nhiều lỗi thời gian chạy đang chạy pylint .


2
+1 cho môn vị. Tôi đã không biết về nó. Lần tới khi tôi thực hiện một dự án bằng Python, tôi sẽ thử. Ngoài ra, đa luồng có vẻ hoạt động tốt nếu bạn sử dụng Jython thay vì triển khai CPython tham chiếu. OTOH Jython có phần chậm hơn CPython, vì vậy điều này có thể đánh bại một phần mục đích.
dsimcha

3
Threading không được hỗ trợ tốt? Các thư viện luồng đã ở đó từ trước 2.1.
rox0r

2
Tôi biết có hỗ trợ luồng, nhưng so với Java hoặc C, GIL sẽ thực sự làm giảm hiệu suất của bạn. Đó là lý do tại sao mô-đun đa xử lý được ưa thích hơn luồng.
cmcginty

2
Các tài liệu là tốt nếu bạn có thể quản lý để tìm thấy nó. Googling lớp Java là nhiều dễ dàng hơn Python.
Brendan Long

@Casey Tôi đã làm rõ từ ngữ trong câu trả lời, vì luồng được hỗ trợ, chỉ thể hiện một số hiệu suất kỳ lạ (thêm một tham chiếu và một vài liên kết đến tài liệu)
dbr

28

Có thể cho rằng , việc thiếu kiểu gõ tĩnh, có thể đưa ra một số lỗi thời gian chạy nhất định , không xứng đáng với tính linh hoạt bổ sung mà kiểu gõ vịt cung cấp.


5
Điều này là chính xác, mặc dù có những công cụ như PyChecker có thể kiểm tra lỗi mà trình biên dịch trong các ngôn ngữ như C / Java sẽ làm.
Oliver Weiler

24
Gõ động là một quyết định thiết kế có ý thức, không phải là một nhược điểm.
missingfaktor

14
Cũng giống như nói điểm yếu của Java là thiếu kiểu gõ động.
MAK

12
@missingfaktor, @MAK, rõ ràng gõ vịt là một tính năng dự định. Nhưng hầu hết các quyết định thiết kế giới thiệu lợi ích khách quan và nhược điểm. Tính linh hoạt của mã được thêm vào là một lợi ích của việc gõ động và các lớp bổ sung của lỗi thời gian chạy tiềm ẩn là một nhược điểm. Phần chủ quan là liệu tính năng này có đáng không.
Jacob

6
Thiếu kiểu gõ tĩnh giúp lập trình viên dễ dàng viết mã có lỗi thời gian chạy. Trong C #, int foo = 4; Console.Write(foo.Length);không biên dịch, do đó, lỗi "Int32 không có thuộc tính Độ dài" không thể vô tình xâm nhập vào phần mềm được xuất bản. Trong python, trừ khi bạn chạy các công cụ phụ tùy chọn để tìm kiếm các lỗi như vậy, mã truy cập các thành viên không tồn tại của các đối tượng có thể không bị phát hiện cho đến khi nó kết thúc gây ra lỗi thời gian chạy.
Jacob

27

Tôi nghĩ rằng các phần hướng đối tượng của Python cảm thấy "bị khóa". Toàn bộ nhu cầu truyền "bản thân" cho mọi phương pháp là một triệu chứng mà thành phần OOP của nó không được lên kế hoạch rõ ràng , bạn có thể nói; nó cũng cho thấy các quy tắc phạm vi đôi khi của Python bị chỉ trích trong một câu trả lời khác.

Biên tập:

Khi tôi nói các bộ phận hướng đối tượng của Python cảm thấy "bị khóa", tôi có nghĩa là đôi khi, phía OOP cảm thấy khá không nhất quán. Lấy Ruby, ví dụ: Trong Ruby, mọi thứ đều là một đối tượng và bạn gọi một phương thức bằng obj.methodcú pháp quen thuộc (tất nhiên là ngoại trừ các toán tử quá tải); trong Python, mọi thứ cũng là một đối tượng, nhưng một số phương thức bạn gọi là hàm; tức là, bạn quá tải __len__để trả về độ dài, nhưng gọi nó bằng cách sử dụng len(obj)thay vì obj.lengthphổ biến hơn (và nhất quán) phổ biến trong các ngôn ngữ khác. Tôi biết có những lý do đằng sau quyết định thiết kế này, nhưng tôi không thích chúng.

Ngoài ra, mô hình OOP của Python không có bất kỳ loại bảo vệ dữ liệu nào, nghĩa là không có thành viên riêng tư, được bảo vệ và công khai; bạn có thể bắt chước chúng bằng cách sử dụng ___trước các phương thức, nhưng nó thật là xấu xí. Tương tự, Python cũng không hoàn toàn hiểu được khía cạnh truyền thông điệp của OOP.


17
Tham số tự chỉ đơn thuần là làm cho rõ ràng những gì các ngôn ngữ khác để lại ẩn. Những ngôn ngữ đó rõ ràng có một tham số "tự".

13
@Roger Pate: Có, nhưng nhu cầu rõ ràng về "bản thân" là một loại phiền toái (và, tôi sẽ tranh luận, một sự trừu tượng bị rò rỉ). Nó cũng không được đưa ra như một quyết định thiết kế có chủ ý, nhưng do các quy tắc phạm vi "kỳ lạ" của Python. Tôi không thể tìm thấy bài viết một cách nhanh chóng, nhưng có một bài đăng email từ Guido van Rossum giải thích độc đáo tại sao tham số "tự" là bắt buộc.
mipadi

2
@Roger Pate: Trong các ngôn ngữ hướng đối tượng, việc chuyển mục tiêu làm tham số đầu tiên vẫn có thể được coi là một chi tiết triển khai. Tuy nhiên, quan điểm của tôi không phải là ý tưởng tốt hay không; vấn đề là ở Python, đó không phải là do quyết định thiết kế có ý thức, mà là để khắc phục mụn cóc trong hệ thống phạm vi.
mipadi

3
@mipadi: Bản cập nhật có lý do tốt hơn (vì vậy tôi sẽ xóa downvote), nhưng nếu bạn xem len là toán tử mà bạn quá tải, thì đó là OO trong Python. Rất thích xem một ví dụ hoặc lý do về cách Python chuyển thông điệp sai.

8
Tự rõ ràng là một kết quả của thực tế rằng các phương thức chỉ là các hàm (và, như Winston đã lưu ý, ẩn các khai báo biến cục bộ). Bạn không muốn quyết định thiết kế đó, nhưng gọi OOP là "bắt vít" bằng ngôn ngữ mà mọi thứ đều có thể truy cập được như một đối tượng trong thời gian chạy là điều ngớ ngẩn.
ncoghlan

19

Những điều tôi không thích về Python:

  1. Threading (Tôi biết nó đã được đề cập rồi, nhưng đáng được đề cập trong mỗi bài viết).
  2. Không hỗ trợ cho các hàm ẩn danh nhiều dòng (chỉ lambdacó thể chứa một biểu thức).
  3. Thiếu một hàm / lớp đọc đầu vào đơn giản nhưng mạnh mẽ (như cinhoặc scanftrong C ++ và C hoặc Scannertrong Java).
  4. Tất cả các chuỗi không phải là unicode theo mặc định (nhưng được cố định trong Python 3).

5
Về (2), tôi nghĩ rằng điều này được bù đắp bởi khả năng có các hàm lồng nhau.
Konrad Rudolph

3
@KonradRudolph Phẩm chất chính của tôi với các hàm lồng nhau thay vì lambdas nhiều dòng là thứ tự đọc được hoán đổi.
CookieOfFortune

2
@wkschwartz: raw_inputvà 'sys.stdin' là những barebones đẹp. Họ không hỗ trợ nhận đầu vào được định dạng (ví dụ: "% d:% d:% d"% (giờ, phút, giây) để đọc kịp thời). Cho đến nay Python không có bất cứ điều gì tiếp cận chức năng của scanf (trong C) hoặc Scanner (Java).
MAK

2
@limscoder: Tất cả các chuỗi là unicode theo mặc định trong Java. Tôi không thấy một lý do chính đáng để có các lớp str và unicode riêng biệt. IMHO, chuỗi và mảng byte không nên được biểu diễn bằng cùng một sự trừu tượng hóa. Một lớp chuỗi nên dành cho việc lưu trữ và thao tác văn bản - có đại diện bên trong mà chúng ta không thực sự quan tâm. Chúng ta không nên làm những việc như cắt / thay thế / xóa / chèn tại một byte cụ thể trong một chuỗi - chúng ta muốn làm điều này ở một ký tự cụ thể . Thật dễ dàng để quên sự khác biệt và làm cho mã của bạn nổ tung khi được cung cấp đầu vào không phải tiếng Anh.
MAK

1
@limscoder: nếu bạn muốn xem unicode dễ dàng, hãy thử Tcl. Tôi đã phải chuyển từ Tcl sang Python vài năm trước và cậu bé rất ngạc nhiên khi thấy sự hỗ trợ unicode nguyên thủy của con trăn so sánh. Nó thực sự vô hình trong Tcl, và một nỗi đau lớn ở trăn.
Bryan Oakley

18

Đối số mặc định với các loại dữ liệu có thể thay đổi.

def foo(a, L = []):
    L.append(a)
    print L

>>> foo(1)
[1]
>>> foo(2)
[1, 2]

Nó thường là kết quả của một số lỗi tinh vi. Tôi nghĩ sẽ tốt hơn nếu nó tạo một đối tượng danh sách mới bất cứ khi nào cần một đối số mặc định (thay vì tạo một đối tượng để sử dụng cho mỗi lệnh gọi hàm).

Chỉnh sửa: Đó không phải là một vấn đề lớn, nhưng khi một cái gì đó cần được đề cập trong các tài liệu, nó thường có nghĩa là nó là một vấn đề. Điều này không nên được yêu cầu.

def foo(a, L = None):
    if L is None:
        L = []
    ...

Đặc biệt là khi đó nên được mặc định. Đó chỉ là một hành vi kỳ lạ không phù hợp với những gì bạn mong đợi và không hữu ích cho nhiều trường hợp.


Tôi thấy rất nhiều khiếu nại về điều này, nhưng tại sao mọi người cứ khăng khăng có một danh sách trống (mà hàm sửa đổi) làm đối số mặc định? Đây thực sự là một vấn đề lớn như vậy? Tức là, đây có phải là một vấn đề thực sự ?
Martin Vilcans

8
Nó vi phạm nguyên tắc ít bất ngờ nhất. Người ta sẽ không mong đợi các tham số của hàm tồn tại qua các cuộc gọi.
aib

Đó là một hệ quả của nó là một ngôn ngữ kịch bản. Bạn sẽ chỉ bị cản trở bởi lỗi này ONCE, và không bao giờ trở lại. Tìm ra lỗi này cho chính bạn thực sự mang lại cho bạn một cú đá vào mông để nhắc nhở bạn rằng có, đây vẫn là một ngôn ngữ kịch bản. Và đó chỉ là vì ngôn ngữ rất tốt trong việc che giấu khía cạnh kịch bản (giả sử bạn sử dụng nó một cách chính xác).
Zoran Pavlovic

@ZoranPavlovic vì tò mò, tại sao đây là hậu quả của việc nó là một ngôn ngữ kịch bản? Nó dường như là một vấn đề khi dữ liệu bị ràng buộc và bởi vì danh sách có thể thay đổi (đó là hai điều thường tốt, nhưng cuối cùng lại xấu khi kết hợp với nhau). Vấn đề tương tự có thể xảy ra với ngôn ngữ không có kịch bản nếu bạn ràng buộc dữ liệu tại thời điểm tạo chức năng thay vì tạo danh sách mới mỗi lần hàm được gọi.
jsternberg

@aib: Tôi không nghĩ vậy - tham số ở đây, giống như mọi đối tượng Python khác - là một con trỏ tới một đối tượng. Trong trường hợp này, đối tượng là một đối tượng có thể thay đổi và biến bị ràng buộc khi hàm được khai báo. Tham số này "tồn tại qua các cuộc gọi", nhưng những gì còn tồn tại là tham chiếu đến một đối tượng có thể thay đổi.
Patrick Collins

14

Một số tính năng của Python làm cho nó trở nên linh hoạt như một ngôn ngữ phát triển cũng được coi là nhược điểm lớn của những thứ được sử dụng cho phân tích tĩnh "toàn bộ chương trình" được thực hiện bởi quá trình biên dịch và liên kết trong các ngôn ngữ như C ++ và Java.

  • Khai báo ngầm định các biến cục bộ

Các biến cục bộ được khai báo bằng cách sử dụng câu lệnh gán thông thường. Điều này có nghĩa là các ràng buộc biến trong bất kỳ phạm vi nào khác yêu cầu chú thích rõ ràng được trình biên dịch chọn (khai báo toàn cục và không nhắm mục tiêu cho phạm vi bên ngoài, ký hiệu truy cập thuộc tính cho phạm vi ví dụ). Điều này giúp giảm đáng kể số lượng nồi hơi cần thiết khi lập trình, nhưng có nghĩa là các công cụ phân tích tĩnh của bên thứ ba (như pyflakes) là cần thiết để thực hiện kiểm tra được trình biên dịch xử lý bằng các ngôn ngữ yêu cầu khai báo biến rõ ràng.

  • "Khỉ vá" được hỗ trợ

Nội dung của các mô-đun, các đối tượng lớp và thậm chí không gian tên dựng sẵn có thể được sửa đổi trong thời gian chạy. Điều này là vô cùng mạnh mẽ, cho phép nhiều kỹ thuật cực kỳ hữu ích. Tuy nhiên, tính linh hoạt này có nghĩa là Python không cung cấp một số tính năng phổ biến cho các ngôn ngữ OO được nhập tĩnh. Đáng chú ý nhất là tham số "tự" cho các phương thức thể hiện rõ ràng hơn là ẩn (vì "phương thức" không phải được định nghĩa trong một lớp, chúng có thể được thêm vào sau bằng cách sửa đổi lớp, nghĩa là nó không thực tế để vượt qua tham chiếu thể hiện ngầm) và các điều khiển truy cập thuộc tính không thể được thực thi dựa trên việc mã có "bên trong" hay "bên ngoài" lớp hay không (vì sự phân biệt đó chỉ tồn tại trong khi định nghĩa lớp được thực thi).

  • Xa kim loại

Điều này cũng đúng với nhiều ngôn ngữ cấp cao khác, nhưng Python có xu hướng trừu tượng hóa hầu hết các chi tiết phần cứng. Các ngôn ngữ lập trình hệ thống như C và C ++ vẫn phù hợp hơn nhiều để xử lý truy cập phần cứng trực tiếp (tuy nhiên, Python sẽ khá vui vẻ nói chuyện với những người đó thông qua các mô-đun mở rộng CPython hoặc, thông qua ctypesthư viện hơn).


12
  1. Sử dụng thụt lề cho các khối mã thay vì {} / start-end, bất cứ điều gì.
  2. Mọi ngôn ngữ hiện đại mới hơn đều có phạm vi từ vựng phù hợp, nhưng không phải là Python (xem bên dưới).
  3. Tài liệu hỗn loạn (so sánh với tài liệu Perl5, đó là tuyệt vời).
  4. Áo khoác ngoài eo biển (chỉ có một cách để làm điều đó).

Ví dụ cho phạm vi bị hỏng; bảng điểm từ phiên dịch:

>>> x=0
>>> def f():
...     x+=3
...     print x
... 
>>> f()
Traceback (most recent call last):
  File "", line 1, in ?
  File "", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment

globalnonlocalcác từ khóa đã được giới thiệu để vá lỗi ngu ngốc thiết kế này.


2
liên quan đến phạm vi, có thể đáng để những người tò mò nhìn vào python.org/dev/peps/pep-3104 để hiểu lý do của phương pháp hiện tại.
Winston Ewert

Đồng ý với +1. Vì vậy, +1.
Jas

34
Có một cách để làm điều đó là một lợi thế. Khi bạn đọc mã của người khác, bạn không giải mã được từng câu lệnh. Một khi các thành ngữ được gắn kết trong bộ não của bạn, bạn sẽ nhận ra ngay lập tức.
rox0r

9
Hoàn toàn đồng ý với @ rox0r. "Áo khoác thẳng" ngăn chặn tất cả các loại cuộc chiến cú pháp.
keithjgrant

8
Thành thật mà nói, tôi rất hiếm khi cần globalhoặc nonlocaltừ khóa trong Python. Vì vậy, hiếm khi tôi quên vấn đề này tồn tại và phải google lại nó vài lần, mặc dù thực tế là tôi viết mã Python mỗi ngày tại nơi làm việc. Đối với tôi, mã cần sửa đổi các biến toàn cục (hoặc tệ hơn là các biến ngoài toàn cầu) là một mùi mã. Thường có (không phải luôn luôn) một cách tốt hơn.
Ben

11

Tôi thấy sự kết hợp của cú pháp của python về cú pháp hướng đối tượng this.method()và thủ tục / chức năng method(this)rất đáng lo ngại:

x = [0, 1, 2, 3, 4]
x.count(1)
len(x)
any(x)
x.reverse()
reversed(x)
x.sort()
sorted(x)

Điều này đặc biệt xấu vì một số lượng lớn các hàm (chứ không phải các phương thức) chỉ được đưa vào không gian tên toàn cục : các phương thức liên quan đến danh sách, chuỗi, số, hàm tạo, siêu lập trình, tất cả được trộn lẫn trong một danh sách lớn được sắp xếp theo thứ tự bảng chữ cái.

Ít nhất, các ngôn ngữ chức năng như F # có tất cả các chức năng được đặt tên đúng trong các mô-đun:

List.map(x)
List.reversed(x)
List.any(x)

Vì vậy, họ không phải là tất cả với nhau. Hơn nữa, đây là một tiêu chuẩn được tuân theo trong toàn bộ thư viện, vì vậy ít nhất nó cũng phù hợp.

Tôi hiểu lý do để thực hiện chức năng so với phương thức , nhưng tôi vẫn nghĩ rằng việc trộn chúng như thế này là một ý tưởng tồi. Tôi sẽ vui hơn nhiều nếu cú ​​pháp phương thức được tuân theo, ít nhất là cho các hoạt động chung:

x.count(1)
x.len()
x.any()
x.reverse()
x.reversed()
x.sort()
x.sorted()

Cho dù các phương thức có đột biến hay không, có chúng là các phương thức trên đối tượng có một số lợi thế:

  • Một nơi duy nhất để tra cứu các hoạt động "phổ biến" trên kiểu dữ liệu: các thư viện khác / v.v. có thể có những thứ ưa thích khác mà chúng có thể làm với các kiểu dữ liệu nhưng các hoạt động "mặc định" đều nằm trong các phương thức của đối tượng.
  • Không cần phải lặp lại Modulekhi gọi Module.method(x). Lấy ví dụ về Danh sách chức năng ở trên, tại sao tôi phải nói đi nói Listlại? Nó nên biết rằng đó là một Listvà tôi không muốn gọi Navigation.map()hàm trên nó! Sử dụng x.map()cú pháp giữ cho nó KHÔ và vẫn không rõ ràng.

Và tất nhiên nó có lợi thế so với cách làm việc trong không gian tên toàn cầu . Không phải là cách hiện tại không có khả năng hoàn thành công việc. Nó thậm chí còn khá ngắn gọn ( len(lst)), vì không có gì được đặt tên! Tôi hiểu những lợi thế của việc sử dụng các hàm (hành vi mặc định, v.v.) so với các phương thức, nhưng tôi vẫn không thích nó.

Nó chỉ lộn xộn. Và trong các dự án lớn, sự lộn xộn là kẻ thù tồi tệ nhất của bạn.


1
vâng ... Tôi thực sự nhớ phong cách LINQ (Tôi chắc chắn LINQ không phải là người đầu tiên thực hiện nó, nhưng tôi quen thuộc nhất với nó) xử lý danh sách.
CookieOfFortune

1
Đừng nghĩ về len (x) như một phương pháp. "len" là một chức năng. Python có các hàm phương thức và tôi thấy không có gì sai với cách tiếp cận đó. Thiếu các chức năng thích hợp, thông thường, là nguồn của rất nhiều gõ không cần thiết.
rbanffy

Tôi biết len()là một chức năng, và những lợi thế là gì. Tôi cũng đã nêu lý do tại sao tôi nghĩ đó là một ý tưởng tồi, tại sao tôi nghĩ các chức năng toàn cầu là một ý tưởng đặc biệt tồi tệ và tại sao tôi nghĩ các phương pháp cung cấp một phương pháp thuận tiện để tổ chức và phân tích chức năng của bạn =)
Haoyi

Tôi không nghĩ rằng 42 (hoặc là 43?) Từ khóa là một số lượng lớn. Điều đó cũng bao gồm những thứ như def, classvà các cuộc gọi không chức năng khác. So sánh với 100+ trong hầu hết các ngôn ngữ phổ biến khác. Ngoài ra, hãy xem xét các dòng từ import this: Namespaces are one honking great idea -- let's do more of those!. Tôi nghĩ rằng bạn có thể hiểu nhầm không gian tên Python;)
Wayne Werner

8

Thiếu tính đồng nhất .

Python phải đợi 3.x để thêm từ khóa "với". Trong bất kỳ ngôn ngữ đồng âm nào, nó có thể được thêm vào trong thư viện.

Hầu hết các vấn đề khác tôi đã thấy trong các câu trả lời là một trong 3 loại:

1) Những thứ có thể được sửa bằng công cụ (ví dụ: pyflakes) 2) Chi tiết triển khai (GIL, hiệu suất) 3) Những thứ có thể được sửa bằng các tiêu chuẩn mã hóa (ví dụ như các tính năng mọi người muốn không có ở đó)

# 2 không phải là vấn đề với ngôn ngữ, IMO # 1 và # 3 không phải là vấn đề nghiêm trọng.


1
withđã có sẵn từ Python 2.5 from __future__ import with_statement, nhưng tôi đồng ý, đôi khi tôi thấy không may là các câu như if/ for/ print/ etc là "đặc biệt" thay vì các hàm thông thường
dbr

7

Python là ngôn ngữ yêu thích của tôi vì nó rất biểu cảm, nhưng vẫn khiến bạn không mắc quá nhiều lỗi. Tôi vẫn còn một vài điều làm tôi khó chịu:

  • Không có chức năng ẩn danh thực sự. Lambda có thể được sử dụng cho các hàm lệnh đơn và withcâu lệnh có thể được sử dụng cho nhiều thứ mà bạn sử dụng khối mã trong Ruby. Nhưng trong một số tình huống, nó làm cho mọi thứ trở nên vụng về hơn một chút so với họ. (Khác xa với sự vụng về như trong Java, nhưng vẫn ...)

  • Một số nhầm lẫn trong mối quan hệ giữa các mô-đun và các tập tin. Chạy "python foo.py" từ dòng lệnh khác với "nhập foo". Nhập khẩu tương đối trong Python 2.x cũng có thể gây ra vấn đề. Tuy nhiên, các mô-đun của Python tốt hơn nhiều so với các tính năng tương ứng của C, C ++ và Ruby.

  • Rõ ràng self. Mặc dù tôi hiểu một số lý do cho nó và mặc dù tôi sử dụng Python hàng ngày, tôi có xu hướng phạm sai lầm khi quên nó. Một vấn đề khác với nó là nó trở nên hơi tẻ nhạt khi tạo một lớp ra khỏi một mô-đun. Tự rõ ràng có liên quan đến phạm vi hạn chế mà những người khác đã phàn nàn. Phạm vi nhỏ nhất trong Python là phạm vi chức năng. Nếu bạn giữ các chức năng của mình nhỏ, như bạn nên, đó không phải là vấn đề của chính nó và IMO thường cung cấp mã sạch hơn.

  • Một số chức năng toàn cầu, chẳng hạn như len, mà bạn mong đợi là một phương thức (mà nó thực sự nằm ở phía sau hậu trường).

  • Lõm đáng kể. Không phải là ý tưởng, mà tôi nghĩ là tuyệt vời, nhưng vì đây là điều duy nhất khiến nhiều người không dùng thử Python, có lẽ Python sẽ tốt hơn với một số biểu tượng bắt đầu / kết thúc (tùy chọn). Bỏ qua những người đó, tôi hoàn toàn có thể sống với một kích thước được thi hành cho vết lõm quá.

  • Rằng nó không phải là ngôn ngữ tích hợp của trình duyệt web, thay vì JavaScript.

Trong số những khiếu nại này, đây chỉ là lần đầu tiên tôi quan tâm đầy đủ đến mức tôi nghĩ rằng nó nên được thêm vào ngôn ngữ. Những cái khác là khá nhỏ, ngoại trừ cái cuối cùng, sẽ rất tuyệt nếu nó xảy ra!


+1 Nó khiến tôi băn khoăn không biết có nên viết datetime.datetime.now()khi một dự án có thể viết datetime.nowvà sau đó trộn hai dự án một cách viết để loại bỏ quy tắc kia hay không và chắc chắn điều này sẽ không xảy ra trong Java, nó sẽ không đặt tên mô-đun giống như một tệp (?) nếu bạn thấy cách phổ biến có vẻ như mô-đun gây nhầm lẫn cho chúng tôi với tệp khi cả hai cách sử dụng đều được thực hiện và rõ ràng, selftôi vẫn cố gắng hiểu vì các cuộc gọi không có cùng số lượng đối số như các hàm. Và bạn có thể nghĩ rằng con trăn VM có chậm không?
Niklas Rosencrantz

Về vấn đề của bạn với các từ khóa rõ ràng. Tôi có thể đề nghị sử dụng IDE python tốt cho điều đó không? Tôi biết PyDev trên Eclipse tự động hoàn thành phần tự của chữ ký hàm nếu nó phát hiện bạn đang viết bên trong một lớp.
Zoran Pavlovic

5

Python chưa hoàn toàn trưởng thành: ngôn ngữ python 3.2 tại thời điểm này có vấn đề tương thích với hầu hết các gói hiện được phân phối (thông thường chúng tương thích với python 2.5). Đây là một nhược điểm lớn hiện đang cần nhiều nỗ lực phát triển hơn (tìm gói cần thiết; xác minh tính tương thích; cân nhắc chọn gói không tốt có thể tương thích hơn; đưa phiên bản tốt nhất, cập nhật lên 3.2 có thể mất vài ngày; bắt đầu làm một cái gì đó hữu ích).

Có khả năng vào giữa năm 2012, điều này sẽ ít trở ngại hơn.

Lưu ý rằng tôi đoán rằng tôi đã bị hạ bệ bởi một fan-boy. Trong một cuộc thảo luận về nhà phát triển, nhóm phát triển cấp cao của chúng tôi đã đưa ra kết luận tương tự.

Trưởng thành theo một nghĩa chính có nghĩa là một nhóm có thể sử dụng công nghệ và rất nhanh chóng & chạy mà không có rủi ro tiềm ẩn (bao gồm các vấn đề tương thích). Các gói python của bên thứ 3 và nhiều ứng dụng không hoạt động dưới 3.2 cho phần lớn các gói hiện nay. Điều này tạo ra nhiều công việc tích hợp, thử nghiệm, tự thực hiện lại công nghệ thay vì giải quyết vấn đề trong tay == công nghệ kém trưởng thành hơn.

Cập nhật cho tháng 6 năm 2013: Python 3 vẫn có vấn đề về sự trưởng thành. Thường thì một thành viên trong nhóm sẽ đề cập đến một gói cần thiết sau đó nói "ngoại trừ nó chỉ dành cho 2.6" (trong một số trường hợp tôi đã triển khai một cách giải quyết thông qua ổ cắm localhost để sử dụng gói chỉ 2.6 với 2.6 và phần còn lại của công cụ của chúng tôi ở lại với 3.2). Ngay cả MoinMoin, wiki python thuần, được viết bằng Python 3.


2
Tôi chỉ đồng ý với bạn nếu định nghĩa về sự trưởng thành của bạn không tương thích với phiên bản không tương thích với thiết kế .
tshepang

3
Tôi đồng ý rằng hai luồng không tương thích của python là một vấn đề (mặc dù có thể hiểu tại sao nó được thực hiện), nhưng tôi không xem đó là vấn đề của "sự trưởng thành".
Winston Ewert

Trưởng thành theo một nghĩa nào đó có nghĩa là một nhóm có thể sử dụng công nghệ và rất nhanh chóng & chạy mà không có rủi ro tiềm ẩn (bao gồm các vấn đề tương thích). Các gói python của bên thứ 3 và nhiều ứng dụng không hoạt động dưới 3.2 cho phần lớn các gói hiện nay. Điều này tạo ra nhiều công việc tích hợp, thử nghiệm, tự thực hiện lại công nghệ thay vì giải quyết vấn đề trong tay == công nghệ kém trưởng thành hơn.
Jonathan Cline IEEE

2
Sau đó, chỉ cần sử dụng Python 2.x. Bạn biết ... phiên bản mà mọi người đang sử dụng. Hoặc đọc tài liệu gói trong 2 giây để tìm ra phiên bản nào tương thích với nó.
jsternberg

2
"Chỉ vì python 3.0 đã được phát hành một thời gian không có nghĩa là phiên bản bạn nên sử dụng. Python 3.0 và 2.x đang được phát triển cùng một lúc. Tôi hy vọng rằng trong tương lai tất cả chúng ta sẽ có thể sử dụng python 3.0, nhưng hiện tại sử dụng 2.x là một giải pháp tốt "-> Đó là cách nói 500 ký tự: Nó chưa trưởng thành.
Jonathan Cline IEEE

4

Phạm vi của Python bị phá vỡ nghiêm trọng, điều này làm cho việc lập trình hướng đối tượng trong Python rất khó xử.


8
bạn có thể đưa ra một ví dụ không? (Tôi chắc chắn rằng bạn đúng, nhưng tôi muốn một ví dụ)
Winston Ewert

24
Tôi thích Python nhưng tôi hoàn toàn khinh khi phải đặt self.trước mọi tham chiếu đến một thuộc tính và phương thức cá thể. Nó khiến cho việc sử dụng Python để tạo DSL giống như là điều rất dễ thực hiện trong Ruby.
Adam Crossland

35
Tôi không thấy khó xử, tôi thích nhân chứng.
Winston Ewert

9
Tôi không thấy vấn đề lớn về bản thân rõ ràng là gì. Trong C ++, Java và D, mọi người thường làm cho các biến thành viên rõ ràng bằng cách quy ước, ví dụ bằng cách thêm tiền tố vào chúng bằng dấu gạch dưới.
dsimcha

7
Bạn sử dụng self trong các phương thức khác với khai báo của chúng: def foo (self) but self.foo (). Tôi thấy hỗn hợp định nghĩa rõ ràng này nhưng ẩn chứa những thứ hậu trường không quá đẹp.
LennyProgrammer

4

Tôi hiểu về Python:

  • Bolted-on OOP (Xem câu trả lời của @ mipadi để biết thêm chi tiết về điều này)
  • Thực hiện hỏng của lambdas
  • Vấn đề phạm vi
  • Không có bộ sưu tập liên tục trong thư viện tiêu chuẩn
  • Khả năng đáp ứng kém đối với DSL nhúng

Tại sao các downvote?
missingfaktor

Tôi không phải là người hạ cấp, nhưng bạn có thể giải thích lý do tại sao bạn nghĩ rằng OO được bắt đầu không? Python luôn có OO, nó là một phần cốt lõi của ngôn ngữ.
Daenyth

Xem câu trả lời của @ mipadi.
năm11


4

Công cụ sửa đổi truy cập trong Python không thể thực thi - gây khó khăn cho việc viết mã được cấu trúc tốt, được mô đun hóa.

Tôi cho rằng đó là một phần của phạm vi bị hỏng của @ Mason - một vấn đề lớn nói chung với ngôn ngữ này. Đối với mã được cho là có thể đọc được, có vẻ khá khó khăn để tìm ra những gì có thể và nên có trong phạm vi và giá trị sẽ ở bất kỳ thời điểm nào - tôi hiện đang nghĩ đến việc chuyển từ ngôn ngữ Python vì những nhược điểm này .

Chỉ vì "tất cả chúng ta đều là người lớn đồng ý" không có nghĩa là chúng ta không phạm sai lầm và không làm việc tốt hơn trong một cấu trúc mạnh mẽ, đặc biệt là khi làm việc trong các dự án phức tạp - thụt đầu dòng và dấu gạch dưới vô nghĩa dường như không đủ .


Vì vậy, thiếu kiểm soát truy cập là xấu ... nhưng phạm vi rõ ràng của biến ghi vào bất kỳ không gian tên không cục bộ nào cũng xấu?
ncoghlan

@ncoghlan: 1 - tính năng đó là tiêu chuẩn trong nhiều ngôn ngữ hiện đại, tùy thuộc vào cách bạn định cấu hình dự án của mình. 2 -Đó nằm dưới sự kiểm soát của lập trình viên. 3 - không chắc điều gì tuyệt vời về điều đó - bạn có thể dễ dàng kiểm soát phạm vi của mình bằng một vài cài đặt dự án bằng hầu hết các ngôn ngữ / IDE được biên dịch. Nếu "tất cả chúng ta đều đồng ý với người lớn", chúng ta sẽ có thể tự đưa ra quyết định và điều chỉnh phạm vi theo mức độ thoải mái cụ thể của mình.
Vector

2
Vấn đề là những người yêu cầu "các điều khiển truy cập được thi hành" đang yêu cầu chúng tôi loại bỏ một trong những điều khiến Python trở thành một ngôn ngữ keo tuyệt vời như vậy: thật khó để các nhà phát triển kiểm soát cách sử dụng mã của họ sau này. Có bao nhiêu mẫu soạn sẵn trong các mẫu C ++ và Java chỉ có để làm việc xung quanh các điều khiển truy cập được thi hành? Tôi chắc chắn có thể hiểu mọi người chọn không sử dụng Python vì những lý do đó, nhưng việc thực thi tĩnh sẽ không bao giờ thay thế cho việc kiểm tra nghiêm ngặt.
ncoghlan

1
@ncoghlan - với tôi những điều tuyệt vời về Python là sự tao nhã của cú pháp và sự gọn gàng - tính biểu cảm. Và như tôi đã nói, phạm vi ít liên quan đến các lập trình viên gây rối với những thứ họ không nên làm hơn với cấu trúc và tổ chức mã - vì vậy khái niệm 'đồng ý với người lớn' là không phù hợp. Tôi làm việc trên các dự án phức tạp, không phải các tiện ích và tập lệnh đơn giản - mã phải được mô đun hóa và cấu trúc cẩn thận - công cụ sửa đổi truy cập là một trong những cách quan trọng nhất để đảm bảo điều đó.
Vector

1
Và xem xét mã, đào tạo và phân tích khớp nối là những người khác. Đối với tôi, các điều khiển truy cập được thi hành rơi vào cùng một nhóm như gõ tĩnh: chúng giúp cung cấp thêm độ tin cậy về tính chính xác (nhưng không đủ để tránh sự cần thiết phải thử nghiệm rộng rãi), nhưng với chi phí cao trong năng suất phát triển. (Ở mức thực tế, các điều khiển truy cập thuộc tính lớp cũng không phù hợp với mô hình đối tượng của Python trong đó các phương thức chỉ là các hàm thông thường được lấy từ các lớp. Ranh giới "bên trong / bên ngoài" cho các lớp không thực sự tồn tại, vì vậy nó không thể tồn tại thi hành)
ncoghlan

3
  1. Hiệu suất không tốt, nhưng được cải thiện với pypy,
  2. GIL ngăn chặn việc sử dụng luồng để tăng tốc mã, (mặc dù điều này thường là tối ưu hóa sớm),
  3. Nó chỉ hữu ích cho lập trình ứng dụng,

Nhưng nó có một số tính năng đổi thưởng tuyệt vời:

  1. Nó hoàn hảo cho RAD,
  2. Thật dễ dàng để giao tiếp với C (và cho C để nhúng trình thông dịch python),
  3. Nó rất dễ đọc,
  4. Thật dễ để học
  5. Nó được ghi chép lại,
  6. Pin thực sự được bao gồm, thư viện tiêu chuẩn của nó rất lớn và pypi chứa các mô-đun cho tất cả mọi thứ,
  7. Nó có một cộng đồng lành mạnh.

Điều gì truyền cảm hứng để đề cập đến những lợi thế? Câu hỏi cho các vấn đề. Dù sao, ý bạn là nó chỉ hữu ích cho lập trình ứng dụng? Có chương trình nào khác không? Điều gì đặc biệt là nó không tốt cho?
tshepang

5
Tôi liệt kê những lợi thế bởi vì tôi nghĩ rằng chúng vượt trội hơn những nhược điểm. Bạn đã bao giờ thử thực hiện một mô-đun hạt nhân linux trong python.
dan_waterworth

3

Tôi rất thích python và nhược điểm đầu tiên xuất hiện trong đầu tôi là khi bình luận một tuyên bố như thế if myTest():thì bạn phải thay đổi thụt lề của toàn bộ khối thực thi mà bạn sẽ không phải làm với C hoặc Java. Thực tế là trong python thay vì bình luận một mệnh đề if thay vào đó tôi đã bắt đầu bình luận nó theo cách này: `if True: #myTest () vì vậy tôi cũng sẽ không phải thay đổi khối mã sau. Do Java và C không dựa vào thụt lề nên nó giúp cho việc nhận xét các câu lệnh dễ dàng hơn với C và Java.


1
Bạn nghiêm túc chỉnh sửa mã C hoặc Java để thay đổi cấp độ khối của một số mã mà không thay đổi thụt lề?
Ben

4
@Ben Tạm thời, có ...
thay thế

1
@ben giống nhau đây.
Christopher Mahan

2
Tôi sử dụng thủ thuật thay đổi if something()thành if False and something(). Một mẹo khác là "bình luận" bằng cách sử dụng chuỗi nhiều dòng.
Martin Vilcans

1
@Martin Tất nhiên! nếu sai ...
Christopher Mahan

3

Nhiều công văn không tích hợp tốt với hệ thống loại công văn đơn được thiết lập và không hiệu quả lắm.

Tải động là một vấn đề lớn trên các hệ thống tệp song song trong đó ngữ nghĩa giống POSIX dẫn đến sự chậm chạp thảm khốc cho các hoạt động chuyên sâu về siêu dữ liệu. Tôi có các đồng nghiệp đã đốt cháy một phần tư triệu giờ lõi chỉ để nhận Python (với numpy, mpi4py, petc4py và các mô-đun mở rộng khác) được tải trên lõi 65k. (Mô phỏng đã mang lại một kết quả khoa học mới đáng kể, vì vậy nó đáng giá, nhưng đó là một vấn đề khi hơn một thùng dầu được đốt để tải Python một lần.) thời gian tải hợp lý ở quy mô, bao gồm vá libc-rtld để thực dlopenhiện truy cập hệ thống tệp tập thể.


Wow, có vẻ kỹ thuật cao, bạn có bất kỳ tài liệu tham khảo, ví dụ, bài viết blog hoặc bài viết về chủ đề này? Tôi tự hỏi nếu tôi có thể tiếp xúc với những trường hợp như vậy trong một tương lai gần.
vincent

Aron đã nói chuyện tại SciPy 2012 . Các dlopencông cụ là trong thư viện collfs của chúng tôi . Kho lưu trữ đó cũng chứa các thủ thuật zipimport bổ sung được lấy cảm hứng từ bộ nhớ đệm đường dẫn của Asher Langton. Chúng tôi đang làm việc về phân phối tốt hơn và một bài báo.
Jed

3
  • khá nhiều thư viện và phần mềm bên thứ 3 rất chính thống được sử dụng rộng rãi, không phải là pythonic. Một vài ví dụ: Soaplib, opensp, reportlab. Phê bình nằm ngoài phạm vi, nó ở đó, nó được sử dụng rộng rãi, nhưng nó làm cho văn hóa trăn khó hiểu (nó làm tổn thương phương châm nói rằng "Nên có một - và tốt nhất là chỉ có một cách rõ ràng để làm điều đó"). Những thành công pythonic được biết đến (như django hoặc trac) dường như là ngoại lệ.
  • độ sâu không giới hạn của khả năng trừu tượng của thể hiện, lớp, siêu dữ liệu là khái niệm đẹp và độc đáo. Nhưng để thành thạo nó, bạn phải hiểu sâu về trình thông dịch (theo thứ tự mã python được diễn giải, v.v.). Nó không được biết đến và sử dụng rộng rãi (hoặc được sử dụng một cách chính xác), trong khi ma thuật đen tương tự như thuốc generic C #, về mặt khái niệm thì phức tạp hơn (IMHO) dường như được biết đến và sử dụng rộng rãi hơn, theo tỷ lệ.
  • để có thể nắm bắt tốt bộ nhớ và mô hình luồng, bạn phải khá có kinh nghiệm với python, vì không có thông số kỹ thuật toàn diện. Bạn chỉ cần biết những gì hoạt động, có thể bởi vì bạn đọc các nguồn của thông dịch viên hoặc những người kỳ quặc có kinh nghiệm và khám phá ra cách khắc phục chúng. Chẳng hạn, chỉ có các tham chiếu mạnh hay yếu, không phải là các ref mềm và ảo của java. Java có một luồng cho bộ sưu tập rác trong khi không có câu trả lời chính thức về thời điểm bộ sưu tập rác xảy ra trong python; bạn chỉ có thể quan sát rằng bộ sưu tập rác không xảy ra nếu không có mã python nào được thực thi và kết luận đôi khi nó có thể xảy ra khi cố gắng phân bổ bộ nhớ. Có thể khó khăn khi bạn không biết tại sao tài nguyên bị khóa không được phát hành (kinh nghiệm của tôi về điều đó là mod_python trong freeswitch).

Nhưng dù sao, python là ngôn ngữ chính của tôi trong 4 năm nay. Trở thành fanboy, elitists hoặc monomaniacs không phải là một phần của văn hóa trăn.


+1. Spec cho bộ nhớ và mô hình luồng là đúng. Nhưng FWIW, trình thu gom rác Java nằm trên một luồng (và hầu hết mọi thứ khác về GC) không phải là một khía cạnh của ngôn ngữ Java hoặc các đặc tả VM mỗi se, mà là vấn đề triển khai của JVM cụ thể. Tuy nhiên, Sun / Oracle JVM chính được ghi lại rộng rãi về hành vi và cấu hình của wrt GC, đến mức có toàn bộ sách được xuất bản về điều chỉnh JVM. Về lý thuyết, người ta có thể ghi lại CPython theo cùng một cách, bất kể thông số ngôn ngữ.
Andrew Janke

2
  • OOP lạ lùng:
    • len(s)thông qua __len__(self)và các "phương pháp đặc biệt" khác
    • các phương pháp đặc biệt khác có thể được bắt nguồn từ các phương pháp đặc biệt khác ( __add____iadd__cho ++=)
    • self như tham số phương thức đầu tiên
    • bạn có thể quên gọi hàm tạo của lớp cơ sở
    • không có sửa đổi truy cập (riêng tư, được bảo vệ ...)
  • không có định nghĩa không đổi
  • không có bất biến cho các loại tùy chỉnh
  • GIL
  • hiệu suất kém dẫn đến sự pha trộn giữa Python và C và các rắc rối với các bản dựng (tìm kiếm C libs, phụ thuộc nền tảng ...)
  • tài liệu xấu, đặc biệt là trong libs của bên thứ ba
  • không tương thích giữa Python 2.x và 3.x
  • các công cụ phân tích mã kém (so với những gì được cung cấp cho các ngôn ngữ được nhập tĩnh như Java hoặc C #)

5
Cá nhân tôi nghĩ rằng sự không tương thích giữa 2.x và 3.x là một trong những lợi thế lớn nhất của Python. Chắc chắn, nó cũng là một bất lợi. Nhưng sự táo bạo của các nhà phát triển để phá vỡ khả năng tương thích ngược cũng có nghĩa là họ không phải thực hiện hành trình bất tận. Nhiều ngôn ngữ cần một cuộc đại tu như vậy.
Konrad Rudolph

0

"Bất biến" không chính xác là điểm mạnh của nó. Số AFAIK, bộ dữ liệu và chuỗi là bất biến, mọi thứ khác (tức là các đối tượng) đều có thể thay đổi. So sánh điều đó với các ngôn ngữ chức năng như Erlang hoặc Haskell nơi mọi thứ đều bất biến (ít nhất là theo mặc định).

Tuy nhiên, Tính bất biến thực sự thực sự tỏa sáng với sự tương tranh *, cũng không phải là điểm mạnh của Python, vì vậy ít nhất đó là kết quả.

. tuyệt vời ngay cả khi không có sự tương tranh.))


0

Tôi muốn có các cấu trúc song song rõ ràng. Thường xuyên hơn không, khi tôi viết một danh sách hiểu

[ f(x) for x in lots_of_sx ]

Tôi không quan tâm thứ tự các yếu tố sẽ được xử lý. Đôi khi, tôi thậm chí không quan tâm đến thứ tự chúng được trả lại.

Ngay cả khi CPython không thể làm tốt khi f của tôi là Python thuần túy, hành vi như thế này có thể được xác định cho các triển khai khác sử dụng.


// sinh ra các chuỗi các chủ đề // truyền hàng đợi hàng đợi cho tất cả các chủ đề que.extend ([x for x in lots_of_sx]) que.wait () # Đợi tất cả lot_of_sx được xử lý bởi các luồng.
Zoran Pavlovic

0

Python không tối ưu hóa cuộc gọi đuôi, chủ yếu là vì lý do triết học . Điều này có nghĩa là đệ quy đuôi trên các cấu trúc lớn có thể tiêu tốn bộ nhớ O (n) (vì ngăn xếp không cần thiết được giữ lại) và sẽ yêu cầu bạn viết lại đệ quy dưới dạng vòng lặp để có bộ nhớ O (1).

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.