Tôi có nên thực sự sử dụng tất cả chữ hoa cho các hằng số của mình không?


34

Tôi là một lập trình viên Python chủ yếu sử dụng pylint cho mã nguồn. Tôi có thể loại bỏ tất cả các cảnh báo ngoại trừ một: Tên không hợp lệ cho hằng số. Thay đổi tên thành tất cả các mũ sửa nó, nhưng tôi thực sự phải làm điều đó? Nếu tôi làm điều đó, tôi thấy rằng mã của tôi trông xấu vì hầu hết các biến là không đổi (theo pylint).


1
Nếu hầu hết các biến của bạn là hằng số cấp mô-đun, có lẽ bạn đang làm điều gì đó bất thường. Hầu hết trong số họ nên sống bên trong các chức năng.
RemcoGerlich

1
bạn có thể chỉ cho chúng tôi một mẫu mã của bạn mà pylint nghĩ là hằng số không?
Winston Ewert

@WinstonEwertNOTES_DIRECTORY = argv[1] chdir(NOTES_DIRECTORY) FILES = glob('*.txt') RAND_FILE = choice(FILES) with open(RAND_FILE) as notes_file: POINTS = notes_file.readlines() RAND_POINT = choice(POINTS)
Abhishek Kumar

@AbhishekKumar, mã của bạn trong một hàm, hoặc ở cấp cao nhất?
Winston Ewert

@WinstonEwert Ở cấp cao nhất và sau khi làm theo hướng dẫn của PyLint.
Abhishek Kumar

Câu trả lời:


33

Có lẽ bạn đang viết mã như thế này:

notes_director = argv[1]
chdir(notes_director)
files = glob('*.txt')
rand_file = choice(files)
with open(rand_file) as notes_file: 
    points = notes_file.readlines() 
    rand_point = choice(points)

Bạn nên di chuyển mã này vào một hàm:

def main():
    notes_director = argv[1]
    chdir(notes_director)
    files = glob('*.txt')
    rand_file = choice(files)
    with open(rand_file) as notes_file: 
        points = notes_file.readlines() 
        rand_point = choice(points)

# actually call the main function    
main()

Pylint giả định rằng mã thực sự làm việc sẽ nằm trong một hàm. Bởi vì bạn có mã này ở cấp cao nhất của mã thay vì bên trong một hàm, nó bị lẫn lộn.

Nói chung, đó là phong cách tốt hơn để làm việc bên trong một chức năng thay vì ở cấp cao nhất. Điều này cho phép bạn tổ chức tốt hơn những gì bạn đang làm và tạo điều kiện tái sử dụng nó. Bạn thực sự chỉ nên có mã thực hiện một thuật toán bên ngoài hàm trong một tập lệnh nhanh và bẩn.


1
Rất không đồng ý, tôi nghĩ rằng có nhiều lý do Pythonic tốt để sử dụng các biến cấp mô-đun. Tôi nghĩ rằng lời khuyên này chỉ đơn thuần là một tạo tác của việc đọc sai môn vị PEP8, và giả sử điều ngược lại của "hằng số phải là cấp độ mô-đun" cũng đúng.
Hệ thống số liệu

21

Vâng. Theo quy tắc PEP8 trên các hằng số :

Các hằng số thường được xác định ở cấp độ mô-đun và được viết bằng tất cả các chữ in hoa có dấu gạch dưới tách các từ. Ví dụ bao gồm MAX_OVERFLOWTOTAL.

Phiên bản dài:

Trong cộng đồng Python (như trong nhiều cộng đồng khác) tồn tại các quy ước về cách viết mã. Điều này khác với mã làm việc : ngay cả khi bạn viết tất cả các chữ thường, mã của bạn vẫn hoạt động.

Nhưng có sự đồng thuận của cộng đồng (như tài liệu trong PEP8) được "thi hành" với các công cụ như pylint . Nếu bạn lập trình cho hạnh phúc của riêng bạn, bạn có thể bỏ qua những gợi ý mà pylint mang lại cho bạn. Nếu bạn muốn trao đổi cởi mở với cộng đồng, còn gọi là »ai đó ngoài tôi nên sử dụng mã của tôi«, bạn nên chuẩn bị mã theo PEP8.


7
Mặt khác, hoàn toàn có thể làm cho pylintnó sai. Python không cung cấp cách phân biệt hằng số với một biến, ngoài ra hằng số được dự kiến ​​sẽ luôn có cùng giá trị. pylintgiả định rằng bất cứ điều gì chỉ được đặt một lần và không bao giờ thay đổi là một hằng số, nhưng trừ khi nó có ý định là một hằng số, đó chỉ có thể là một tạo tác của việc thực hiện. Và cụ thể, mã được đưa ra trong nhận xét cho câu hỏi có các giá trị sẽ khác nhau trên mỗi lần chạy, do đó không nên được coi là hằng số ngay cả khi pylint nghĩ rằng chúng là.
Jules

@Jules Tôi sẽ gọi các biến được đặt một lần và thay đổi trong thời gian chạy không bao giờ là hằng số, do đó tồn tại trong nhiều ngôn ngữ (ví dụ: trong JS) một consttừ khóa. Mặc dù giá trị ban đầu là khác nhau, khác với có thể PI.
Thomas Junk

1
Tôi phân biệt giữa một biến không thay đổi (nghĩa là một cái gì đó được đặt trong thời gian chạy và không thay đổi) và một hằng số (nghĩa là một cái gì đó giống nhau trong mỗi lần chạy chương trình và nếu ngôn ngữ cung cấp tùy chọn để thực hiện thì nó có thể được tính toán trong thời gian biên dịch ) ... vấn đề là bởi vì không có bất kỳ cách nào để xác định sự khác biệt với trăn, pylintgiả định cái sau ngay cả khi cái trước là trường hợp.
Jules

Pylint chắc chắn là sai, trong đó nó đọc "hằng số phải là cấp mô-đun" và giả sử "cấp độ mô-đun nên là hằng số". Nhưng bởi vì nó là một công cụ hữu ích, tốt, dường như chúng ta đang bị mắc kẹt với nó.
Hệ thống số liệu

@MetricSystem cái gì - theo ý kiến ​​của bạn - một biến cấp mô-đun sẽ có gì ngoài việc là một hằng số? Nó có nên biến đổi?
Thomas Junk

13

Chuẩn mực cộng đồng PEP8 và Python là sử dụng ALL_CAPS_CONSTANTS. Đây là một đầu mối trực quan phổ biến, được sử dụng trong nhiều thập kỷ trong C, Java, Perl, PHP, Python, bash và các ngôn ngữ lập trình và môi trường shell khác. Nhưng theo cách nói trực tuyến hiện đại, TẤT CẢ CÁC TÍN HIỆU CAPS . Và la hét là thô lỗ.

Python là, tuy nhiên, không nhất quán về ALL_CAPS_CONSTANTS. JavaScript có thể có Math.PI, nhưng Python thì có math.pi. Không có hằng số dễ nhận biết hoặc lâu dài hơn π. Hoặc xem xét sys.version_info, phiên bản Python bạn đang chạy. Hằng số 100% trong suốt vòng đời của chương trình của bạn - nhiều hơn PORThoặc so với MAX_ITERATIONScác hằng số khác mà bạn xác định. Hay làm thế nào về sys.maxsize? Giá trị nguyên gốc tối đa của nền tảng của bạn là không đổi trong không chỉ một hoặc hai chương trình chạy mà còn cả tuổi thọ của phần cứng của bạn.

Nếu các hằng số này - bao gồm một số như π và e là hằng số cơ bản của vũ trụ, và sẽ không thay đổi trong suốt thời gian vĩnh cửu - nếu chúng có thể là chữ thường, thì ... các hằng số khác cũng vậy. Bạn có thể chọn.

Hãy nhớ rằng, PEP8 là một hướng dẫn phong cách. Một hướng dẫn, không phải là một luật. Một hướng dẫn thường được chống lại ngay cả bởi thư viện tiêu chuẩn của Python. Và trích dẫn một hướng dẫn cốt lõi khác về Python, PEP20 (còn gọi là "Zen của Python"):

  • Đẹp thì tốt hơn xấu.
  • Tính dễ đọc
  • Thực tiễn đánh bại sự tinh khiết.

Trên một lưu ý thực tế, khi một chương trình YELLY_CONSTANTSHOUTY_PARAMETERbắt đầu ghi nhớ, sẽ giúp nhớ rằng các hằng số mũ thường không thực sự là lý tưởng Platonic bền vững , mà là các tham số của chương trình chạy. Không có gì thực sự liên tục về PORT, SITENAMEhoặc NUMRUNS, và họ không phải được quản lý như các chương trình toàn cầu độc lập. Ví dụ, chúng có thể được thả vào từ điển dưới dạng gói tham số chương trình có thể truy cập toàn cầu:

config = {
    'port': 80,
    'sitename': "Bubba's Blog",
    'numruns': 100,
}

Python cũng có một cơ sở tham số từ khóa tốt giúp giảm nhu cầu sử dụng APPARENTLY_ANGRY_GLOBAL_VARIABLES:

def process_data(sitename, port=80, numruns=100):
    ...

process_data("Bubba's Blog")

Trong thực tế, nhiều giá trị trong số này sẽ được (hoặc nên) được đọc từ các tệp cấu hình, biến môi trường hệ điều hành, đối số dòng lệnh hoặc các nguồn khác để đáp ứng nghịch đảo của nguyên tắc / mẫu điều khiển . Nhưng đó là một câu chuyện lớn hơn cho một ngày khác.


1

Vâng, nó khá phổ biến trong hầu hết các ngôn ngữ lập trình (ít nhất là những ngôn ngữ tôi sử dụng).

Bạn có thể tham khảo liên kết Google này để chia sẻ một phong cách chung giữa các nhà phát triển của cùng một nhóm.

Nên sử dụng

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
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.