PEP 8, tại sao không có khoảng trắng xung quanh '=' trong đối số từ khóa hoặc giá trị tham số mặc định?


103

Tại sao PEP 8 khuyến nghị không có khoảng trắng xung quanh =đối số từ khóa hoặc giá trị tham số mặc định ?

Điều này có mâu thuẫn với việc đề xuất khoảng trắng xung quanh mọi lần xuất hiện khác của =mã Python không?

Thế nào là:

func(1, 2, very_long_variable_name=another_very_long_variable_name)

tốt hơn:

func(1, 2, very_long_variable_name = another_very_long_variable_name)

Mọi liên kết đến thảo luận / giải thích bằng BDFL của Python sẽ được đánh giá cao.

Xin lưu ý, câu hỏi này thiên về kwargs hơn là giá trị mặc định, tôi vừa mới sử dụng cụm từ PEP 8.

Tôi không trưng cầu ý kiến. Tôi đang hỏi lý do đằng sau quyết định này. Nó giống như việc hỏi tại sao tôi lại sử dụng {trên cùng một dòng với ifcâu lệnh trong chương trình C, chứ không phải liệu tôi có nên sử dụng nó hay không.

Câu trả lời:


72

Tôi đoán rằng đó là vì một đối số từ khóa về cơ bản khác với một phép gán biến.

Ví dụ, có rất nhiều mã như thế này:

kw1 = some_value
kw2 = some_value
kw3 = some_value
some_func(
    1,
    2,
    kw1=kw1,
    kw2=kw2,
    kw3=kw3)

Như bạn thấy, việc gán một biến cho một đối số từ khóa có tên giống hệt nhau là hoàn toàn hợp lý, do đó, nó cải thiện khả năng đọc khi thấy chúng không có khoảng trắng. Dễ dàng nhận ra rằng chúng ta đang sử dụng các đối số từ khóa và không gán một biến cho chính nó.

Ngoài ra, các tham số có xu hướng đi trên cùng một dòng trong khi các phép gán thường là mỗi một trong một dòng riêng của chúng, vì vậy tiết kiệm không gian có thể là một vấn đề quan trọng ở đó.


6
Đây có thể là trường hợp, nhưng vẫn có vẻ lạ khi giới thiệu tính nhất quán của IMO này trong các đề xuất kiểu mã cho một ngôn ngữ được thiết kế tốt như vậy, chỉ để lưu 2 ký tự. Nó như thể kiểu mã java nói rằng việc đặt {một dòng mới sau if(lưu cùng một số ký tự) nhưng không phải trong định nghĩa lớp. Ngoài ra, một thông số từ khóa khác với giá trị mặc định nhưng vẫn sử dụng cùng một đề xuất kiểu.
soulcheck

3
Như tôi đã nói, chúng là những thứ khác nhau. Nó có ý nghĩa để viết chúng khác nhau.
fortran

6
Tôi muốn nói rằng nó không thực sự dễ đọc hơn kw1 = kw1, kw2 = kw2;) nhưng có lẽ đó là những gì Guido và Barry nghĩ.
soulcheck

1
tôi sẽ chấp nhận cái máy này vì nó khá thuyết phục. sẽ không nhớ một liên kết xác nhận nó mặc dù
soulcheck

5
Thực tế là đối số từ khóa về cơ bản khác với phép gán biến không phải là đối số hợp lệ để có các quy ước khác nhau IMO, bởi vì sự khác biệt đã rõ ràng từ ngữ cảnh. Cái trước xảy ra trong một lệnh gọi hàm và cái sau cần phải đứng một mình ở mức thụt lề hiện tại. IMO, đối với các tên biến dài hơn 5-6 ký tự (tức là trong đời thực đối với hầu hết các ký tự), biến thể có dấu cách dễ đọc hơn.
Axel

13

Tôi sẽ không sử dụng very_long_variable_name làm đối số mặc định. Vì vậy, hãy xem xét điều này:

func(1, 2, axis='x', angle=90, size=450, name='foo bar')

về điều này:

func(1, 2, axis = 'x', angle = 90, size = 450, name = 'foo bar')

Ngoài ra, không có ý nghĩa gì khi sử dụng các biến làm giá trị mặc định. Có lẽ một số biến hằng số (không thực sự là hằng số) và trong trường hợp đó, tôi sẽ sử dụng các tên đều viết hoa, mang tính mô tả nhưng càng ngắn càng tốt. Vì vậy, không có khác_very _...


1
đó là những lập luận từ khóa, một ví dụ tương tự là trong PEP tôi chỉ làm cho nó ít có thể đọc
soulcheck

3
Bạn đang nói (về cơ bản): để làm cho quy tắc không dấu cách trở nên hợp lý, hãy viết các tên biến rất ngắn. Nhưng NẾU một trong những tên biến ish dài, thì quy tắc không có dấu cách tạo ra một môi trường lộn xộn. Lập luận rằng 'nó không phải là một bài tập, vì vậy chúng là những thứ khác nhau' không phù hợp với tôi, bởi vì tôi quan tâm nhiều hơn đến tính dễ đọc hơn là về ngữ nghĩa và bởi vì nếu nó không phải là 'giá trị mặc định cho một bài tập', thì đó là gì nó?
PatrickT

1
@PatrickT Lập luận "đó không phải là một nhiệm vụ, vì vậy chúng là những thứ khác nhau" không giải thích được tại sao lại như vậy (một khái niệm triết học); Nó chỉ giải thích tại sao nó có thể là (một khái niệm cú pháp).
Mateen Ulhaq

11

Có những ưu và nhược điểm.

Tôi rất không thích cách đọc mã tuân thủ PEP8. Tôi không tin vào lập luận mà very_long_variable_name=another_very_long_variable_namecon người có thể đọc được nhiều hơn thế very_long_variable_name = another_very_long_variable_name. Đây không phải là cách mọi người đọc. Đó là một tải trọng nhận thức bổ sung, đặc biệt là trong trường hợp không có tô sáng cú pháp.

Tuy nhiên, có một lợi ích đáng kể. Nếu các quy tắc về khoảng cách được tuân thủ, thì việc tìm kiếm các tham số chỉ sử dụng các công cụ sẽ hiệu quả hơn nhiều.


Chà, nếu bạn tuân thủ việc đặt khoảng trắng xung quanh =, thì việc tìm kiếm bằng các công cụ sẽ không khác gì.
NoName

10

IMO loại bỏ khoảng trống cho args cung cấp nhóm trực quan rõ ràng hơn cho các cặp arg / value; nó trông ít lộn xộn hơn.


Tôi thường thích khoảng trắng, rất nhiều vì vậy tôi có xu hướng đặt khoảng trắng ngay bên trong dấu ngoặc đơn để tất cả các tham số được bao quanh bởi khoảng trắng. Nhưng tôi nghĩ cái arg1=40này dễ đọc hơn vì mối quan hệ rõ ràng hơn.
Charlie Gorichanaz

3

Tôi nghĩ rằng có một số lý do cho điều này, mặc dù tôi có thể chỉ đang hợp lý hóa:

  1. Nó tiết kiệm dung lượng, cho phép nhiều định nghĩa và lệnh gọi hàm phù hợp trên một dòng và tiết kiệm nhiều dung lượng hơn cho chính tên đối số.
  2. Bằng cách kết hợp từng từ khóa và giá trị, bạn có thể dễ dàng tách các đối số khác nhau bằng khoảng trắng sau dấu phẩy. Điều này có nghĩa là bạn có thể nhanh chóng nhìn vào số lượng đối số mà bạn đã cung cấp.
  3. Cú pháp sau đó khác biệt với các phép gán biến, có thể có cùng tên.
  4. Ngoài ra, cú pháp (thậm chí nhiều hơn) khác với các kiểm tra bình đẳng a == bcũng có thể là các biểu thức hợp lệ bên trong một cuộc gọi.

3

Đối với tôi, nó làm cho mã dễ đọc hơn và do đó là một quy ước tốt.

Tôi nghĩ rằng sự khác biệt chính về kiểu dáng giữa phép gán biến và phép gán từ khóa hàm là chỉ nên có một đơn =trên một dòng cho cái trước, trong khi nói chung có nhiều =s trên một dòng cho cái sau.

Nếu không có cân nhắc nào khác, chúng tôi muốn foo = 42làm như vậy foo=42, bởi vì dấu hiệu sau không phải là cách các dấu bằng thường được định dạng, và vì dấu hiệu trước đây phân tách một cách trực quan biến và giá trị bằng khoảng trắng.

Nhưng khi có nhiều phép gán trên một dòng, chúng tôi muốn f(foo=42, bar=43, baz=44)làm như vậy f(foo = 42, bar = 43, baz = 44), vì cái trước phân tách một số bài tập bằng khoảng trắng một cách trực quan, trong khi cái sau thì không, khiến việc xem cặp từ khóa / giá trị ở đâu là khó hơn một chút.

Dưới đây là một cách khác để đặt nó: có một sự nhất quán đằng sau những ước. Tính nhất quán là thế này: "mức độ tách biệt cao nhất" được làm rõ ràng hơn về mặt trực quan thông qua các khoảng trắng. Bất kỳ mức phân tách nào thấp hơn đều không (vì nó sẽ bị nhầm lẫn với khoảng trắng phân tách mức cao hơn). Đối với phép gán biến, mức độ tách biệt cao nhất là giữa biến và giá trị. Đối với phép gán từ khóa chức năng, mức độ tách biệt cao nhất là giữa các phép gán riêng lẻ.

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.