Làm thế nào tôi có thể học cách viết mã Pythonic một cách hiệu quả?


46

Thực hiện tìm kiếm google cho "pythonic" cho thấy một loạt các giải thích. Các trang wikipedia nói:

Một chủ nghĩa thần kinh phổ biến trong cộng đồng Python là pythonic, có thể có một loạt các ý nghĩa liên quan đến phong cách chương trình. Nói rằng mã là pythonic là nói rằng nó sử dụng thành ngữ Python tốt, đó là tự nhiên hoặc thể hiện sự lưu loát trong ngôn ngữ. Tương tự như vậy, để nói về một tính năng giao diện hoặc ngôn ngữ mà nó là pythonic là nói rằng nó hoạt động tốt với các thành ngữ Python, rằng nó sử dụng kết hợp tốt với phần còn lại của ngôn ngữ.

Nó cũng thảo luận về thuật ngữ "unpythonic":

Ngược lại, một dấu hiệu của mã unpythonic là nó cố gắng viết mã C ++ (hoặc Lisp, Perl hoặc Java) trong Python, nghĩa là, cung cấp một phiên âm thô thay vì một bản dịch thành ngữ từ các ngôn ngữ khác. Khái niệm về pythonicity gắn chặt với triết lý tối giản về khả năng đọc của Python và tránh cách tiếp cận "có nhiều hơn một cách để làm điều đó". Mã không thể đọc được hoặc thành ngữ không thể hiểu được là unpythonic.

Thuật ngữ "pythonic" có nghĩa là gì? Làm thế nào để tôi học cách áp dụng nó một cách hiệu quả vào thực tế?


6
Tôi nghĩ rằng câu hỏi của bạn có thể được mở rộng cho bất kỳ ngôn ngữ lập trình. Luôn luôn có một cách lập trình được khuyến nghị có thể chính xác trong một số lượng lớn các trường hợp và cũng để cải thiện việc sửa đổi, dễ đọc và bảo trì. Tôi nghĩ cũng thách thức những khuyến nghị đó có thể làm cho ngôn ngữ phát triển và tiến lên ...
Amine

@Amine thật vậy. Trên thực tế tôi nghĩ rằng một wiki cộng đồng bao gồm chính xác nơi để học thành ngữ ngôn ngữ - cho tất cả các ngôn ngữ - nên được xem xét.
yati sagade


1
Bình luận viên: xin vui lòng ngừng đăng bình luận không liên quan; họ đã bị xóa vì một lý do. Nếu bạn có câu trả lời, hãy để lại câu trả lời. Nếu bạn muốn thảo luận về chủ đề của câu hỏi này, vui lòng sử dụng trò chuyện .

1
Bằng cách thực hành Python!
Năng động

Câu trả lời:


22

Tôi đã thấy rằng hầu hết mọi người đều có những diễn giải riêng về việc "Pythonic" thực sự có nghĩa là gì. Từ Wikipedia:

Một chủ nghĩa thần kinh phổ biến trong cộng đồng Python là pythonic, có thể có một loạt các ý nghĩa liên quan đến phong cách chương trình. Nói rằng mã là pythonic là nói rằng nó sử dụng thành ngữ Python tốt, đó là tự nhiên hoặc thể hiện sự lưu loát trong ngôn ngữ. Tương tự như vậy, để nói về một tính năng giao diện hoặc ngôn ngữ mà nó là pythonic là nói rằng nó hoạt động tốt với các thành ngữ Python, rằng nó sử dụng kết hợp tốt với phần còn lại của ngôn ngữ.

Ngược lại, một dấu hiệu của mã unpythonic là nó cố gắng viết mã C ++ (hoặc Lisp, Perl hoặc Java) trong Python, nghĩa là, cung cấp một phiên âm thô thay vì một bản dịch thành ngữ từ các ngôn ngữ khác. Khái niệm về pythonicity gắn chặt với triết lý tối giản về khả năng đọc của Python và tránh cách tiếp cận "có nhiều hơn một cách để làm điều đó". Mã không thể đọc được hoặc thành ngữ không thể hiểu được là unpythonic.

Tôi đã thấy rằng nhiều lần hơn không, các ví dụ "pythonic" thực sự bắt nguồn từ những người cố gắng thông minh với các thành ngữ Python và (một lần nữa, nhiều lần hơn là không) hiển thị mã của họ hầu như không thể đọc được ( không phải là Pythonic).

Miễn là bạn gắn bó với thành ngữ của Python và tránh cố gắng sử dụng các kiểu C ++ (hoặc ngôn ngữ khác) trong Python, thì bạn đang là Pythonic.

Như WorldEngineer đã chỉ ra, PEP8 là một tiêu chuẩn tốt để tuân theo (và nếu bạn sử dụng VIM, có các plugin có sẵn để nhuộm PEP8).


Thực sự, vào cuối ngày, nếu giải pháp của bạn hoạt động và không hoàn toàn khủng khiếp không thể bảo trì và chậm, ai quan tâm? Nhiều lần hơn không, công việc của bạn là hoàn thành một nhiệm vụ, không phải viết mã pythonic thanh lịch nhất có thể.


Một lưu ý bên (chỉ là ý kiến của tôi, cảm thấy tự do để downvote vì nó;)): Tôi cũng tìm thấy cộng đồng Python được làm đầy với một tấn của cái tôi (không phải là hầu hết các cộng đồng không , nó chỉ là một ít phổ biến hơn trong các cộng đồng như C và Python). Vì vậy, kết hợp bản ngã với những diễn giải sai lầm về "pythonic" sẽ có xu hướng mang lại rất nhiều tiêu cực vô căn cứ. Lấy những gì bạn đọc từ người khác với một hạt muối. Bám sát các tiêu chuẩn và tài liệu chính thức và bạn sẽ ổn thôi.


2
+1 cho một câu trả lời hay (ngoại trừ trích dẫn vì tôi đã sử dụng nó trong OP).

Ugh .. Shoulda đọc lại OP trước khi đăng trích dẫn: P
Demian Brecht

3
Thay vào đó, có một mối tương quan cao giữa cái tôi và hoạt động trực tuyến, bày tỏ ý kiến ​​trong bất kỳ cộng đồng nào . Về cơ bản, bạn không nhìn thấy những người không ích kỷ nhiều như vậy bởi vì họ không viết nhiều như vậy ngay từ đầu.
isarandi

17

Pythonic là mã thành ngữ trong Python. Nó có nghĩa là sử dụng các cấu trúc và định dạng hoạt động tốt cho Python từ quan điểm lập trình mà còn từ quan điểm đọc cộng đồng. Nó rất giống với cách K & R thiết lập tiêu chuẩn cho phong cách lập trình C trong một thời gian dài. Hướng dẫn này cho thấy bạn phải viết mã thành ngữ trong Python. PEP 8 được tham chiếu trong hướng dẫn đó nên có lẽ đáng đọc.


1
@MattFenwick Không phải là 90% về lập trình là gì sao? Các lập trình viên giỏi dành nhiều thời gian để đọc mã và trong thời gian còn lại, hãy viết thật nhiều mã. Bạn càng đọc nhiều mã Pythonic và bạn càng viết nhiều bằng Python, mã của bạn sẽ càng nhiều mã Pythonic. Tôi không nghĩ có bất kỳ phím tắt nào ở đây.
Kris Harper

2
Liên kết tuyệt vời !
Ethan Furman

13

Viết mã "Pythonic" IMHO chỉ là sử dụng hiệu quả các tính năng (V) HLL mà ngôn ngữ cung cấp. Như một ví dụ phổ biến,

x, y = 7, 'fuhrer'

Đó là rất Pythonic. Tôi nhớ khi tôi bắt đầu học C # sau nhiều tháng chỉ có Python,

int x, y = 10, z;

bằng cách nào đó làm tôi bối rối, nhưng phải mất một phút để tôi trở về gốc C / C ++ của mình.

Một cách khác của Pythonic là sử dụng lambdas.

l = [1, 2, 3, 4, 5]
print(sorted(l, key=lambda x: -x))

sẽ thực sự in lsắp xếp theo thứ tự giảm dần.

Sau đó, có rất nhiều từ được sử dụng, nhưng rất ít được hiểu là "gõ vịt" - Nếu nó đi và nói như một con vịt, bạn coi nó như một con vịt. Điều này liên quan lỏng lẻo đến các giao diện trong các ngôn ngữ OO khác.

Ngoài ra sử dụng các phương pháp lập trình chức năng khi áp dụng, chẳng hạn như sử dụng bản đồ và thu nhỏ được coi là pythonic.

Tôi thấy một câu trả lời được đăng khi tôi đang gõ và nó chứa một liên kết đẹp. PS: Không phải là kiến ​​thức về Python của bạn bị hạn chế. Tôi có thể cá rằng Python không phải là ngôn ngữ đầu tiên của bạn, và do đó, (như hầu hết chúng ta là pythonistas), bạn sẽ phải học cách "thành ngữ" với con rắn! Chúc mừng!


Tôi không bao gồm liên kết như đã được đăng khi tôi đang gõ - Câu trả lời của WorldEngine :) Chỉ cần nghĩ đến việc "khai thác" các tính năng ngôn ngữ cho mục đích của bạn và của người khác, và bạn sẽ có được Pythonic trên đường, và vui lòng làm theo liên kết đó
yati sagade

4
Trên thực tế, nhiều người nghi ngờ rằng map, reduce, lambdavà như vậy là thành ngữ cho mỗi gia nhập. Danh sách hiểu và biểu thức trình tạo là một lựa chọn thay thế và nhiều người thích chúng bất cứ khi nào có thể một cách hợp lý (đặc biệt, chúng sẽ ít ồn hơn khi bạn cần một lambda nào). Chúng chắc chắn có công dụng của chúng, và chương trình chức năng hiển thị trong các thành ngữ khác (ví dụ trang trí).

@delnan đồng ý - và thậm chí còn hơn thế khi nói đến Python 3. Kết luận là các tính năng chức năng nên được sử dụng chính xác khi cần thiết. Và điều đó (chỉ có một cách rõ ràng để làm điều đó) là thành ngữ :)
yati sagade

Cá nhân, tôi chưa bao giờ hiểu sở thích của mọi người cho ví dụ đầu tiên của bạn. Điều này dễ dàng hơn nhiều để phân tích tinh thần (Đó Zen của Python, mã được đọc thường xuyên hơn so với nó được viết): (x, y) = (7, 'fuhrer')- nhưng tôi hầu như luôn luôn "sửa" rằng không có parens là cách tốt nhất để viết nó!
Izkata

2
Tôi sẽ lập luận rằng ví dụ sắp xếp cụ thể của bạn không phải là pythonic. Tại sao lại giới thiệu sắp xếp lại với lambda nếu bạn có thể print(sorted(l, reverse=True)), điều này cũng nói rõ cho người đọc biết chuyện gì đang xảy ra. Tôi cũng sẽ tìm thấy ví dụ đầu tiên của bạn gây tranh cãi. Đó là hai bài tập được nén thành một; Không sao đâu, nhưng tôi sẽ không gọi nó là Pythonic. Người đọc phải nhìn lâu hơn những gì nó làm so với việc có hai bài tập.
phresnel

7
--> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Mã Pythonic là:

  • Có thể đọc được
  • Đơn giản (đơn giản nhất có thể, nhưng không đơn giản hơn)
  • Suy nghĩ kỹ

1
+1. Zen của Python quan trọng hơn để viết mã pythonic hơn là theo danh sách các thành ngữ; cái sau sẽ không bao gồm tất cả các trường hợp.
Doval

6

Bất cứ khi nào tôi cố gắng học một ngôn ngữ mới, tôi đã thấy rằng đọc mã bởi những người biết ngôn ngữ như bàn tay của họ, nhìn lên / hỏi về bất cứ điều gì có vẻ kỳ lạ, và sau đó cố gắng bắt chước phong cách của họ là điều tốt nhất để làm Ví dụ:

Trong Python, vì chúng ta đang ở chủ đề này, tôi đã tìm thấy các ví dụ từ Lặn vào Python cực kỳ hữu ích để bắt đầu. Họ có xu hướng không chỉ dạy những điều cơ bản về Python mà còn thực sự nhấn mạnh Python thành ngữ .

Khi học D, vì tài liệu không hay vào thời điểm đó vì ngôn ngữ quá dễ hiểu, tôi đã học bằng cách đọc mã đến thư viện tiêu chuẩn, cụ thể là một số kiệt tác của Andrei Alexandrescu .

Khi học C ++, tôi đã thừa hưởng một codebase từ một lập trình viên C ++ khá giỏi và học được rất nhiều về lập trình C ++ thành ngữ từ sự khăng khăng của anh ấy về việc chuyển các container STL bằng cách tham chiếu, v.v.

Trong tất cả các ngôn ngữ, tôi thấy rằng việc duyệt các câu hỏi StackOverflow về ngôn ngữ và xem xét những gì mọi người thường làm để thực hiện những điều cơ bản giúp ích.


+1 Khi bạn biết những điều cơ bản của ngôn ngữ, đọc mã sẽ giúp ích nhiều hơn so với đọc sách.
Pace

3

Python không phải là Java có thể cung cấp cho bạn một số lời khuyên hữu ích. Không thể nói nhiều hơn mà không biết bạn đang gặp phải vấn đề gì, nhưng đó là lời khuyên rất cụ thể cho các lập trình viên đến từ một ngôn ngữ khác (trong trường hợp cụ thể là java) về cách làm python khác nhau.


2

Có người nói để diễn giải, để tìm hiểu Pythonic là gì, chỉ cần bash ra một số mã. Tôi không đồng ý với điều đó. Nếu bạn thích viết mã dày đặc, điều đó không làm cho nó trở nên nhiều Pythonic hơn.

Một cách để giúp bạn xác định Pythonic là gì liên quan đến bản thân bạn, hãy tự hỏi "Tại sao tôi (nghĩa là bạn) sử dụng ngôn ngữ Python?" Điều gì hấp dẫn bạn về nó?

Đối với tôi nó là khả năng đọc và thiếu biên dịch và nguồn mở (gần như tất cả trong số đó). Tôi có thể tải hàng tấn thư viện và đọc mã nguồn của họ với ít căng thẳng hơn về việc cấp phép sau đó nhiều ngôn ngữ khác.

Đối với tôi Python là đẹp trực quan. Guido (người tạo ra Python) cũng tiếp tục chứng minh cho tôi, thông qua các câu trả lời của anh ấy trong PEPS và các cuộc thảo luận) rằng những lựa chọn của anh ấy về cách anh ấy tạo ra ngôn ngữ là vượt trội so với ý tưởng của tôi về cách nó nên được tạo ra.

Đối với tôi, một lập trình viên tuyệt vời là người có kỹ năng ra quyết định rất sáng suốt về cách đi khi viết mã. Đối với tôi, Python hỗ trợ việc đưa ra những lựa chọn đó một cách nhanh chóng.

Bằng cách đơn giản hóa cú pháp mã nguồn bằng cách cho phép gõ vịt thay vì nhập kiểu explicid và kỳ vọng rằng các lập trình viên xem xét mã của bạn "nên là các lập trình viên hành xử tốt" dẫn đến một cái gì đó tôi cũng gọi là "Pythonic"

Vì vậy, có hai mặt của Pythonic. Một là cú pháp, hai là thực hành. Làm thế nào để giải thích khía cạnh sâu sắc hơn của "Pythonic" ..?

Trong Python, không có vấn đề gì lớn để làm điều này: alist = ['one', 'hai', 'ba \ n'] alist.append ((1234, 'Atuple'))

và bộ dữ liệu sẽ được thêm vào danh sách mà không cần quan tâm đến các loại đối tượng. Phần Pythonic không phải là bạn CÓ THỂ làm điều này, mà là mã của bạn nên MỞ RỘNG điều này và chỉ cần làm việc / thích nghi.

Bất cứ điều gì hoạt động trên đối tượng -alist- nên được viết với ý tưởng rằng một số lập trình viên khác có thể vào và thêm một chuỗi không vào danh sách và việc điều chỉnh mã nguồn của trình mã hóa mới không nên khó thực hiện. Rốt cuộc, đó là lợi ích của ducktype.


-2

Mua một cuốn sách được đề nghị. Đọc nó. Nó sẽ cung cấp cho bạn một cơ sở tốt để sử dụng ngôn ngữ và trong một cơ chế đáp ứng phong cách cộng đồng

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.