Haruskah saya menggunakan semua huruf besar untuk konstanta saya?

34

Saya seorang programmer Python terutama yang menggunakan pylint untuk linting kode sumber. Saya dapat menghilangkan semua peringatan kecuali satu: Nama tidak valid untuk konstanta. Mengganti nama menjadi semua perbaikan memperbaikinya, tetapi apakah saya benar-benar harus melakukan itu? Jika saya melakukannya, saya menemukan bahwa kode saya terlihat jelek karena sebagian besar variabel konstan (menurut pylint).

Abhishek Kumar
sumber
2
Jika sebagian besar variabel Anda adalah konstanta tingkat modul, Anda mungkin melakukan sesuatu yang tidak biasa. Sebagian besar dari mereka harus hidup di dalam fungsi.
RemcoGerlich
1
dapatkah Anda menunjukkan kepada kami contoh kode Anda yang menurut pylint adalah konstanta?
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, apakah kode Anda dalam suatu fungsi, atau di tingkat atas?
Winston Ewert
@ WinstonEwert Di tingkat atas dan setelah mengikuti instruksi PyLint.
Abhishek Kumar

Jawaban:

33

Anda mungkin menulis kode seperti ini:

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)

Anda harus memindahkan kode ini ke fungsi:

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 mengasumsikan bahwa kode yang benar-benar berfungsi akan berada di dalam fungsi. Karena Anda memiliki kode ini di tingkat atas kode Anda dan bukan di dalam fungsi itu jadi bingung.

Secara umum, itu adalah gaya yang lebih baik untuk melakukan pekerjaan di dalam suatu fungsi daripada di tingkat atas. Ini memungkinkan Anda untuk mengatur dengan lebih baik apa yang Anda lakukan dan memfasilitasi penggunaannya kembali. Anda seharusnya hanya memiliki kode yang melakukan algoritme di luar fungsi dalam skrip cepat dan kotor.

Winston Ewert
sumber
1
Sangat tidak setuju, saya pikir ada banyak alasan Pythonic yang baik untuk menggunakan variabel tingkat modul. Saya pikir saran ini hanyalah sebuah artefak dari pylint salah membaca PEP8, dan dengan asumsi kebalikan dari "konstanta harus tingkat modul" juga harus benar.
MetricSystem
21

Iya nih. Menurut aturan PEP8 tentang konstanta :

Konstanta biasanya didefinisikan pada tingkat modul dan ditulis dalam huruf kapital semua dengan menggarisbawahi kata-kata yang memisahkan. Contohnya termasuk MAX_OVERFLOWdan TOTAL.

Versi Panjang:

Di komunitas Python (seperti di banyak komunitas lain) ada konvensi tentang cara menulis kode. Ini berbeda dari kode kerja : walaupun Anda menulis konstanta semua huruf kecil, kode Anda tetap berfungsi.

Tetapi ada konsensus komunitas (seperti yang didokumentasikan dalam PEP8) yang "ditegakkan" dengan alat-alat seperti pylint . Jika Anda memprogram untuk kebahagiaan Anda sendiri, Anda mungkin mengabaikan petunjuk yang diberikan pylint kepada Anda. Jika Anda ingin pertukaran terbuka dengan komunitas, alias »seseorang selain saya harus menggunakan kode saya«, Anda harus menyiapkan kode Anda sesuai dengan PEP8.

Thomas Junk
sumber
7
Di sisi lain, sangat mungkin untuk pylintmelakukan kesalahan. Python tidak menyediakan cara untuk membedakan konstanta dari variabel, selain itu konstanta diharapkan selalu memiliki nilai yang sama. pylintmengasumsikan bahwa apa pun yang hanya ditetapkan sekali dan tidak pernah berubah adalah konstan, tetapi kecuali itu dimaksudkan untuk konstan, itu hanya bisa menjadi artefak dari implementasi. Dan secara khusus kode yang diberikan dalam komentar untuk pertanyaan memiliki nilai yang akan berbeda pada setiap proses, oleh karena itu tidak boleh dianggap sebagai konstanta bahkan jika pylint berpikir demikian.
Jules
@ Jules Saya akan memanggil variabel yang ditetapkan sekali dan berubah selama runtime tidak pernah lagi sebuah konstanta, karenanya ada dalam banyak bahasa (misalnya dalam JS) constkata kunci. Meskipun nilai awal berbeda, selain mungkin PI.
Thomas Junk
1
Saya akan membedakan antara variabel yang tidak berubah (yaitu sesuatu yang ditetapkan pada saat runtime dan tidak berubah) dan konstanta (yaitu sesuatu yang sama di setiap program yang dijalankan, dan jika bahasa yang menyediakan opsi untuk melakukannya dapat dikomputasi pada waktu kompilasi ) ... intinya adalah bahwa karena tidak ada cara untuk menentukan perbedaan ke python, pylintmengasumsikan yang kedua bahkan ketika yang pertama adalah kasusnya.
Jules
Pylint pasti salah, karena membaca "konstanta harus tingkat modul" dan mengasumsikan sebaliknya "tingkat modul harus konstanta". Tetapi karena ini merupakan alat yang baik dan berguna, sepertinya kita terjebak dengannya.
MetricSystem
@ MetrikSistem apa - menurut pendapat Anda - fungsi variabel tingkat modul selain konstan? Haruskah itu bisa berubah?
Thomas Junk
13

Norma komunitas PEP8 dan Python harus digunakan ALL_CAPS_CONSTANTS. Ini adalah petunjuk visual yang umum, yang digunakan selama beberapa dekade di C, Java, Perl, PHP, Python, bash, dan bahasa pemrograman lainnya serta lingkungan shell. Tetapi dalam bahasa online modern, SEMUA CAPS TANDA-TANDA TANGAN BERANDA . Dan berteriak itu kasar.

Namun, Python agak tidak konsisten ALL_CAPS_CONSTANTS. JavaScript mungkin ada Math.PI, tetapi Python memilikinya math.pi. Tidak ada yang lebih dikenal atau konstan konstan daripada π. Atau pertimbangkan sys.version_info, versi Python yang Anda jalankan. 100% konstan selama umur program Anda - lebih dari PORTatau MAX_ITERATIONSkonstanta lain yang akan Anda tetapkan. Atau bagaimana sys.maxsize? Nilai integer asli maksimum platform Anda adalah konstan, bukan hanya pada satu atau dua program yang berjalan, tetapi juga masa pakai perangkat keras Anda.

Jika konstanta-konstanta ini - termasuk beberapa seperti π dan e yang merupakan konstanta fundamental alam semesta, dan tidak akan bervariasi di sepanjang kekekalan - jika mereka dapat lebih rendah, yah ... demikian juga konstanta lainnya. Kamu bisa memilih.

Ingat, PEP8 adalah panduan gaya. Pedoman, bukan hukum. Sebuah pedoman sering dilanggar bahkan oleh perpustakaan standar Python. Dan mengutip pedoman inti Python lain, PEP20 (alias "The Zen of Python"):

  • Cantik lebih baik daripada jelek
  • Jumlah keterbacaan diperhitungkan
  • Kepraktisan mengalahkan kemurnian.

Pada catatan praktis, ketika sebuah program YELLY_CONSTANTdan SHOUTY_PARAMETERmulai untuk parut, itu membantu untuk mengingat bahwa konstanta semua-caps umumnya tidak benar-benar abadi cita-cita Platonis , tetapi parameter dari program yang dijalankan. Tidak ada yang benar-benar konstan tentang PORT,, SITENAMEatau NUMRUNS, dan mereka tidak harus dikelola sebagai global program mandiri. Misalnya, mereka dapat dimasukkan ke dalam kamus sebagai kumpulan parameter program yang dapat diakses secara global:

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

Python juga memiliki fasilitas melewati parameter kata kunci yang bagus yang mengurangi kebutuhan untuk menggunakan APPARENTLY_ANGRY_GLOBAL_VARIABLES:

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

process_data("Bubba's Blog")

Dalam praktiknya, banyak dari nilai-nilai ini akan (atau seharusnya) dibaca dari file config, variabel lingkungan OS, argumen baris perintah, atau sumber lain untuk memenuhi inversi prinsip / pola kontrol . Tapi itu cerita yang lebih besar untuk hari lain.

Jonathan Eunice
sumber
1

Ya, itu cukup umum di sebagian besar bahasa pemrograman (setidaknya yang saya gunakan).

Anda dapat merujuk ke tautan Google ini untuk berbagi gaya yang sama antara pengembang dari tim yang sama.

Disarankan untuk digunakan

Type                  |Public          |Internal
Global/Class Constants|CAPS_WITH_UNDER |_CAPS_WITH_UNDER
alain.janinm
sumber