0
fokus pada
0
Pengikut

Python: Sila berhati-hati di tempat-tempat ini

Dicipta dalam: 2016-12-29 13:46:12, dikemas kini pada:
comments   0
hits   1385

Python: Sila berhati-hati di tempat-tempat ini

python adalah bahasa yang sangat menarik. Ia menyediakan banyak perpustakaan standard yang sangat mudah dan banyak perintah terbina dalam yang memudahkan kita menyelesaikan tugas. Tetapi terlalu banyak perkara baik menyebabkan pilihan yang takut sehingga kita tidak dapat menggunakan perpustakaan standard dan institusi asasnya dengan baik. Berikut adalah beberapa perangkap yang sangat mudah dan berkesan untuk pemula Python.

  • Elakkan versi Python

Ini adalah isu yang selalu dibangkitkan di StackOverflow. Jadi, anda perlu memeriksa versi Python anda untuk memastikan ia konsisten. Pastikan kod anda berjalan pada versi Python yang anda tahu. Anda boleh melihat versi Python dengan kod berikut:

  $ python --version
  Python 2.7.9

Pentadbiran versi Python

pyenv adalah alat pentadbir versi Python yang bagus.*Pada sistem nix. Pada Mac OS, anda boleh memasang pyenv dengan mudah dengan brew install. Pada sistem Linux, terdapat pemasang automatik (automatic installer)

  • Terjebak dalam menyelesaikan semua masalah dengan satu baris kod

Ramai yang berbangga dengan saya kerana saya dapat menyelesaikan semua masalah dengan satu baris kod, walaupun kod mereka lebih tidak cekap daripada yang ditulis secara normal, dan kod ini lebih sukar dibaca, dan bahkan bercanggah.

  l = [m for a, b in zip(this, that) if b.method(a) != b for m in b if not m.method(a, b) and reduce(lambda x, y: a + y.method(), (m, a, b))]

Sebenarnya, saya menulis kod di atas untuk menjelaskan perkara ini sendiri. Tetapi saya telah melihat banyak orang yang melakukannya. Jika anda hanya menambah sesuatu ke dalam senarai atau set untuk menunjukkan cara anda menyelesaikan masalah yang rumit, anda mungkin tidak akan mendapat apa-apa.

Pengendalian satu baris kod bukanlah satu pencapaian yang besar, walaupun kadang-kadang ia kelihatan sangat bijak. Kod yang baik adalah ringkas tetapi lebih fokus pada kecekapan dan mudah dibaca.

  • Kesalahan inisialisasi set

Ini adalah masalah yang lebih halus, dan kadang-kadang anda tidak akan dapat mengetahuinya.

  >>> { n for n in range(10) if n % 2 == 0 }
  {0, 8, 2, 4, 6}
  >>> type({ n for n in range(10) if n % 2 == 0 })

Contoh di atas menunjukkan bahawa set adalah seperti list dalam bekas. Perbezaannya ialah set tidak mempunyai nilai berulang dan tidak teratur. Orang biasanya menganggap {} sebagai set kosong, tetapi ia tidak, ia adalah dikte kosong.

  >>> {}
  {}
  >>> type({})

Jadi, jika kita ingin menginisialisasi set kosong, kita boleh menggunakan set ()

  >>> set()
  set()
  >>> type(set())

Perhatikan satu set kosong boleh dinyatakan sebagai set (), tetapi satu set yang mengandungi unsur-unsur harus didefinisikan sebagai set ().[1, 2])

  • Salah faham GIL

GIL (global interpreter lock) bermaksud hanya satu thread yang boleh dijalankan dalam satu program Python pada bila-bila masa. Ini bermakna apabila kita tidak boleh membuat satu thread dan mengharapkannya berjalan selari. Apa yang sebenarnya dilakukan oleh penterjemah Python adalah menukar dengan cepat thread yang berbeza. Tetapi ini adalah versi yang sangat mudah.

Ramai orang akan cuba untuk membela Python dengan mengatakan bahawa mereka adalah benang yang sebenar. 3 Ini memang benar, tetapi tidak mengubah fakta bahawa Python memproses benang dengan cara yang berbeza daripada yang anda harapkan.

Penyelesaian yang ditetapkan adalah menggunakan modul multiprocessing. Kelas proses yang disediakan oleh modul multiprocessing pada dasarnya dapat menutupi perbezaan dengan baik. Walau bagaimanapun, perbezaan jauh lebih mahal daripada kos utas. Oleh itu, operasi selari tidak selalu baik.

Walau bagaimanapun, masalah ini tidak berlaku untuk setiap program Python. PyPy-stm adalah contoh satu implemensi Python yang tidak terjejas oleh GIL. Implemensi yang dibina di platform lain seperti JVM (Jython) atau CLR (IronPython) tidak mempunyai masalah GIL.

Jadi, berhati-hatilah apabila menggunakan thread, kerana anda mungkin tidak akan mendapat apa yang anda mahukan.

  • Menggunakan kelas gaya yang ketinggalan zaman

Terdapat dua jenis kelas dalam Python 2 iaitu kelas gaya lama dan kelas gaya baru. Jika anda menggunakan Python 3, anda menggunakan kelas gaya baru secara default. Untuk memastikan anda menggunakan kelas gaya baru dalam Python 2, anda perlu mewarisi objek atau apa-apa kelas baru yang anda buat yang tidak selalu mewarisi perintah int atau list.

  class MyNewObject(object): # stuff here

Kelas-kelas baru ini memperbaiki beberapa masalah asas yang terdapat dalam kelas lama, dan jika anda berminat boleh lihat dokumentasi.

  • Kesalahan pengulangan

Kesilapan berikut adalah perkara biasa yang dilakukan oleh pemula:

  for name_index in range(len(names)):
    print(names[name_index])

Jelas sekali, tidak perlu menggunakan len, dan sebenarnya, anda boleh mengembara melalui senarai dengan kata-kata yang sangat mudah:

  for name in names:
     print(name)  

Selain itu, terdapat banyak alat lain yang anda boleh gunakan untuk mempermudahkan iterasi. Sebagai contoh, zip boleh digunakan untuk mengkaji dua senarai:

  for cat, dog in zip(cats, dogs):
     print(cat, dog)

Jika kita ingin mempertimbangkan indeks dan senarai nilai, kita boleh menggunakan enumerate.

  for index, cat in enumerate(cats):
     print(cat, index)

Terdapat banyak lagi ciri-ciri dalam itertools yang boleh anda pilih. Jika ia mempunyai ciri-ciri yang anda mahukan, ia sangat mudah untuk anda gunakan. Tetapi jangan terlalu menggunakannya untuk menggunakannya.

Penyalahgunaan itertools menyebabkan salah seorang daripada ahli StackOverflow mengambil masa yang lama untuk menyelesaikannya.

Penggunaan parameter lalai yang boleh berubah

Saya telah melihat banyak perkara seperti ini:

  def foo(a, b, c=[]):
     # append to c
     # do some more stuff

Jangan gunakan parameter lalai yang boleh berubah, dan jangan gunakan:

  def foo(a, b, c=None):
   if c is None:
     c = []
     # append to c
     # do some more stuff 

Contoh berikut boleh membantu kita memahami masalah ini secara intuitif:

  In[2]: def foo(a, b, c=[]):
  ...     c.append(a)
  ...     c.append(b)
  ...     print(c)
  ...
  In[3]: foo(1, 1)
  [1, 1]
  In[4]: foo(1, 1)
  [1, 1, 1, 1]
  In[5]: foo(1, 1)
  [1, 1, 1, 1, 1, 1]

C yang sama dirujuk berulang-ulang kali setiap kali fungsi ini dipanggil. Ini mungkin membawa kepada beberapa akibat yang sangat tidak perlu.