Python: Perhatikan tempat-tempat ini.

Penulis:Ilidhan, Dicipta: 2016-12-29 13:46:12, Dikemas kini:

Python: Perhatikan tempat-tempat ini.

python是一门非常有趣的语言。它提供了许多非常方便的标准库和许多内置命令是我们轻松完成任务.但是好东西太多了就有选择恐惧症了,以至于我们不能很好第利用这个标准库和它的基本机构。下面列出了一些对python新手来说很简单有效的陷阱。

  • Mengecualikan versi Python

    Ini adalah satu masalah yang terus dibangkitkan di StackOverflow. Apabila kod sempurna anda berjalan di komputer orang lain, anda perlu memeriksa sama ada versi Python anda adalah sama. Pastikan kod anda berjalan pada versi Python yang anda tahu.

    $ python --version
    Python 2.7.9
    

    Pentadbiran versi python

    pyenv adalah alat pengurusan versi python yang baik. Malangnya, ia hanya berfungsi pada sistem *nix. Pada Mac OS, anda boleh memasang pyenv dengan mudah dengan menggunakan brew install.

  • Terjebak dalam menyelesaikan semua masalah dengan satu baris kod

    Ramai yang berbangga bahawa saya telah menyelesaikan semua masalah dengan satu baris kod, walaupun kod mereka kurang cekap daripada yang ditulis secara normal, dan kod ini akan menjadi lebih sukar dibaca dan bahkan menjadi salah faham; contoh:

    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))]
    

    Sejujurnya, kod di atas adalah saya sendiri yang menulis untuk menjelaskan perkara ini. Tetapi saya benar-benar melihat banyak orang yang melakukannya. Jika anda hanya menunjukkan diri anda sebagai penyelesaian masalah yang rumit dengan hanya menambahkan sesuatu ke dalam senarai atau set, anda mungkin tidak akan mendapat bayaran.

    Satu baris kawalan kod bukanlah satu pencapaian yang besar, walaupun kadang-kadang kelihatan sangat pintar. Kod yang baik adalah ringkas tetapi lebih memberi tumpuan kepada kecekapan dan mudah dibaca.

  • Set yang tidak disiapkan

    这是一个更加微妙的问题,有时候会让你措手不及。set推导式起来有点像list推导式.

    >>> { 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 ini. Set agak seperti meletakkan senarai dalam bekas. Perbezaannya adalah bahawa set tidak mempunyai nilai berulang dan tidak teratur. Orang biasanya menganggap {} sebagai set kosong, tetapi tidak, ia adalah dikt kosong.

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

    Jadi jika kita mahu menginisialisasikan satu set kosong, kita hanya perlu menggunakan set ((()

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

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

  • Salah faham GIL

    GIL (global interpreter lock) bermaksud hanya satu utas dalam satu program Python yang boleh dijalankan pada bila-bila masa. Ini bermakna apabila kita tidak boleh membuat satu utas dan mengharapkan ia untuk dijalankan secara selari. Penerjemah Python sebenarnya melakukan pertukaran cepat antara pelbagai utas yang dijalankan. Tetapi ini adalah versi yang sangat mudah.

    Ramai orang akan cuba memberi alasan kepada Python bahawa semua ini adalah benang sebenar. 3 Ini benar, tetapi tidak mengubah fakta bahawa Python menangani benang dengan cara yang berbeza daripada yang anda harapkan. Ruby juga mempunyai keadaan yang sama (dan terdapat kunci penerjemah).

    Penyelesaian yang ditetapkan ialah menggunakan modul multiprosesing. Proses yang disediakan modul multiprosesing pada dasarnya dapat menutup perbezaan dengan baik. Walau bagaimanapun, perbezaan jauh lebih tinggi daripada kos benang. Oleh itu, berjalan secara selari tidak selalu baik.

    Walau bagaimanapun, ini bukan masalah yang akan dihadapi oleh setiap program Python. PyPy-stm adalah satu contoh pelaksanaan Python yang tidak dipengaruhi oleh GIL. Pelaksanaan yang dibina pada platform lain seperti JVM (Jython) atau CLR (IronPython) tidak mempunyai masalah GIL.

    Secara ringkasnya, berhati-hatilah apabila menggunakan kelas-kelas thread, anda mungkin tidak mendapat apa yang anda mahukan.

  • Menggunakan kelas gaya usang

    Terdapat dua jenis kelas dalam Python 2, iaitu kelas lama dan kelas gaya baru. Jika anda menggunakan Python 3, anda menggunakan kelas gaya baru secara lalai. Untuk memastikan anda menggunakan gaya baru pada kelas Python 2, anda perlu mewarisi object atau apa-apa kelas baru yang anda buat yang tidak selalu mewarisi arahan binaan int atau list. Dalam erti kata lain, kelas asas anda, harus selalu mewarisi object.

    class MyNewObject(object): # stuff here
    

    Ini adalah satu-satunya pembalut baru yang memperbaiki beberapa masalah asas yang terdapat dalam kelas lama.

  • Iterasi yang salah

    Kesalahan berikut adalah perkara yang biasa dilakukan oleh pemula:

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

    Jelas sekali, tanpa perlu menggunakan len, anda sebenarnya boleh melintas senarai dengan kalimat yang sangat mudah:

    for name in names:
       print(name)  
    

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

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

    Jika kita mahu memikirkan indeks dan senarai nilai, kita boleh menggunakan enumerate.

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

    Terdapat banyak lagi ciri yang boleh dipilih di iTools. Jika iTools mempunyai ciri yang anda mahukan, ia mudah untuk mendapatkannya. Tetapi jangan terlalu menggunakannya untuk menggunakannya.

    Penggunaan itertools yang salah menyebabkan seorang dewa besar di StackOverflow mengambil masa yang lama untuk menyelesaikannya.

    Menggunakan parameter lalai yang boleh ditukar

    Saya telah melihat banyak perkara seperti:

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

    Jangan gunakan parameter lalai yang boleh diubah, gunakan:

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

    Contoh berikut dapat membantu kita memahami masalah ini dengan mudah:

    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 kali setiap kali fungsi dipanggil. Ini mungkin mempunyai beberapa akibat yang sangat tidak diingini.


Lebih lanjut