より多くのPythonスタイルのコードを書く方法

プログラミングと理解が容易になるため、私たちは皆Pythonが好きです。しかし、注意しないと、ルールを無視して、Python以外の方法で大量のガベージコードを記述します。そのため、Pythonの優れた言語が提供する優雅さを無駄にします。Pythonのコーディングスタイルは非常にエレガントで、明確でシンプルです。Pythonインタープリターの実装は、import thisTim Peters PythonZenの準備を見ることができます。

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

ここで私は最高の中国語版を見つけました:

美しさは醜いよりも優れています

明示的は暗黙的よりも優れています

複雑よりも単純な方が良い

複雑な方が複雑な方が良い

フラットはネストよりも優れています

スパースは混雑よりも優れています

読みやすさが重要です

コードは清潔さよりも重要ですが、

私たちが考える特別なケースは、上記のルールを破らなければならないほど特別ではないことがよくあります

わざと黙っていない限り、理由もなく例外を無視しないでください

あいまいなロジックに遭遇した場合は、巧妙な推測をしないでください。

明確な解決策を1つ、できれば1つだけ提供する必要があります

もちろん、あなたがオランダ人でない限り、これを一夜にして行うことはできません[1]。

もちろん、絶対にやらないよりはすぐに始めるほうがいいです。

ただし、慎重に考えずに無謀に行うよりは、絶対に行わない方がよいでしょう。

実装を説明するのが難しい場合、それは良い考えではないはずです

実装が十分に単純であっても、それは良い方法かもしれません

ネームスペースダファは良いです、あなたがそれをしなければ、あなたは人間ではありません!

[1]:この記事の著者であるTim petersは、ここでのオランダ語はPythonの著者であるGuido vanRossumを指していると説明しました。

Pythonでより良いコードを書くための8つの方法は次のとおりです。

1.Cのような言語スタイルを忘れる

リスト内のすべての要素とそのインデックスを印刷する必要がある場合、最初に考えることは次のとおりです。

for i in range(len(arr)):
    print(i, arr[i])

それからあなたはまだCコードを書いています。これを取り除くには、Pythonキーワードが列挙することに注意してください。リスト/文字列内のすべての要素にインデックスを付け、インデックスの開始番号の設定サポートします

>>> for index, item in enumerate(['a','b','c']): 
...     print(index, item)
... 
0 a
1 b
2 c
>>> for index, item in enumerate(['a','b','c'],1): #这里第二个参数可以设置起始编号
...     print(index,item)
... 
1 a
2 b
3 c

今ではより良く、よりPythonicに見えます。リストを文字列に変換するのはどうですか?あなたが書く場合:

# The C way
string = ''
for i in arr:
    string += i

これはCスタイルです。Pythonキーワードjoinを使用すると、効率が向上するだけでなく、よりエレガントになります。

# The Python way
string = ''.join(arr)

参加するのと同じように、Pythonには多くの魔法のキーワードがあるので、その言語では機能しないでください。ただし、その言語を使用して機能してください。

2、PEP8を覚えておいてください

PEP8に完全に従うようにお願いしているわけではありませんが、ほとんどのルールに従うようにお願いしています。さらに、コードをより美しくするのに十分な自動フォーマットツールがたくさんあります。Pythonの父も言っています:コードをもっと頻繁に読むコードを書く頻度よりもはるかに高いので、彼はとても正しいです!したがって、コードの読みやすさは非常に重要です。

あなたが書いたコードに興味がありますか?なぜあなたはこれを書くのですか、なぜこの文はここにあるのですか?そうですね、PEP8はこれらの質問のほとんどに対する答えです。コードコメントは良い方法ですが、変数i、j、countなど、コードのスタイルも調整する必要があります。最初にコメントを書き込んだとしても、後で覚えておく保証はありません。これは貴重な無駄です。時間。

通常のプログラマーなら誰でも、コンピューターが理解できるコードを書くことができます。人間が理解できるコードを書くことができるのは、優れたプログラマーだけです。

CamelCaseがクラスとして、UPPER_WITH_UNDERSCORESが定数として、lower_with_underscoresが変数、メソッド、およびモジュール名として推奨されます。使用する場合でも、単一名関数lambdaの使用は避けてください。

三、控除をうまく利用する

一般的に使用される控除は、リスト控除、セット控除、および辞書控除です。次のリストの理解について話させてください。

リスト内包表記は、既存のリストに基づいて新しいリストを作成する必要がある場合に使用される構文形式です。リスト内包表記には、次の4つの部分が含まれます。

1.入力シーケンス(入力シーケンス)2。入力シーケンスのメンバーを表す変数(変数)3。変数が満たす条件を表すオプションの述語式(オプションの述語)4。出力シーケンス、 2と3に基づいて出力シーケンスを生成します(出力式)

たとえば、数字と文字の両方を含むリストがある場合は、数字の2乗を計算して、結果を新しいリストに入れる必要があります。リストの理解が必要ない場合、記述されるコードは次のようになります。

# bad code
a_list = [1, ‘4’, 9, ‘a’, 0, 4]

squared_ints = []
for item in a_list:
    if type(item) == types.IntType:
        squared_ints.append(item**2)

リスト内包表記を使用する場合、必要なコードは2行だけで、非常にエレガントです。

a_list = [1, ‘4’, 9, ‘a’, 0, 4]
squared_ints = [ e**2 for e in a_list if type(e) == types.IntType ]

もちろん、マップとフィルターが好きな場合でも、これを行うことができますが、読みやすさが悪いため、当時は推奨されていませんでした。

map(lambda e: e**2, filter(lambda e: type(e) == types.IntType, a_list))

たとえば、セット内包表記の使用:

与えられた入力

names = [ 'Bob', 'JOHN', 'alice', 'bob', 'ALICE', 'J', 'Bob' ]

取得したい:

{ 'Bob', 'John', 'Alice' }

次に、設定された理解は次のとおりです。

{ name[0].upper() + name[1:].lower() for name in names if len(name) > 1 }

別の例は、辞書の理解です。

mcase = {'a':10, 'b': 34, 'A': 7, 'Z':3}

mcase_frequency = { k.lower() : mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys() }

# mcase_frequency == {'a': 17, 'z': 3, 'b': 34}

上から見ることができます。推論スタイルのコードはエレガントで人間が読めるものです。

4.まだファイルを明示的に閉じていますか?

上の図のプログラマーのように、コードの記述中にファイルを明示的に閉じている場合は、プログラミング言語で作業しています。コンテキストマネージャーでwithを使用する方法を学習している場合は、Pythonプログラマーであり、プログラミング言語をあなたが働いている:

with open('filename.txt', 'w') as filename:
    filename.write('Hello')

プログラムがwithブロックを終了すると、ファイルは自動的に閉じられます。withステートメントの構文形式:

with VAR as EXPR:
    BLOCK

と同等です:

mgr = (EXPR)
exit = type(mgr).__exit__  # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
    try:
        VAR = value  # Only if "as VAR" is present
        BLOCK
    except:
        # The exceptional case is handled here
        exc = False
        if not exit(mgr, *sys.exc_info()):
            raise
        # The exception is swallowed if exit() returns true
finally:
    # The normal and non-local-goto cases are handled here
    if exc:
        exit(mgr, None, None, None)

with機能を提供する多くのネットワーク接続とデータベース接続ライブラリがあります。withの実装メカニズムに精通した後でも、with関数を自分で実装できます。

class File(object):
    def __init__(self, file_name, method):
        self.file_obj = open(file_name, method)
    def __enter__(self):
        return self.file_obj
    def __exit__(self, type, value, traceback):
        self.file_obj.close()

定義したら、次のステートメント__enter____exit__メソッドを使用できます。

with File('demo.txt', 'w') as opened_file:
    opened_file.write('Hola!')

5、イテレーターとジェネレーターを使用する

イテレーター:イテレータージェネレーター:ジェネレーター

イテレーターとジェネレーターはどちらもPythonの強力なツールであり、習得する価値があります。イテレーターはより一般的な概念です。オブジェクトが属するクラスに__next__メソッド(Python 2のnext)とselfを返す__iter__メソッドがある限り、オブジェクトはイテレーターです。

すべてのジェネレーターはイテレーターですが、その逆はありません。ジェネレータは、1つ以上のyield式を使用して関数を呼び出すことによって構築され、関数は前の段落のイテレータの定義を満たすオブジェクトです。

使用の違い:

インターネット上の多くの技術ブロガーは、ジェネレーターはイテレーターの怠惰なバージョンであり、イテレーターよりも多くのメモリを節約すると言っていますが、実際には間違っています。それらはすべてメモリを節約します(例を示します)。

それらの本当の違いは、複雑な状態維持動作を備えたクラスが必要な場合、または__next__(and__iter____init__以外のメソッドを公​​開したい場合は、ジェネレーターではなくカスタムイテレーターが必要です。

通常、ジェネレーター(場合によっては、単純な要件の場合はジェネレーター式)で十分であり、コードを作成する方が簡単です。

たとえば、aからbまでの正の整数の直接二乗を計算するには(bはaよりはるかに大きい)、ジェネレータは次のようになります。

def squares(start, stop):
    for i in range(start, stop):
        yield i * i

generator = squares(a, b)

または:

generator = (i*i for i in range(a, b))

イテレーターの場合は、次のようになります。

class Squares(object):
    def __init__(self, start, stop):
       self.start = start
       self.stop = stop
    def __iter__(self): return self
    def __next__(self): # next in Python 2
       if self.start >= self.stop:
           raise StopIteration
       current = self.start * self.start
       self.start += 1
       return current

iterator = Squares(a, b)

イテレータを作成するのは少し面倒であることがわかります。たとえば、現在のメソッドを提供する場合など、イテレータがより柔軟な場合は、それをSquaresクラスに直接追加できます。

    def current(self):
       return self.start

上記から、イテレーターがaとbの間のすべての値を保存するわけではなく、すべての値があまり多くのメモリを消費しないことがわかります。これは自分でテストすることもできます。コードは次のとおりです。

>>> from collections.abc import Iterator
>>> from sys import getsizeof
>>> a = [i for i in range(1001)]
>>> print(type(a))
<class 'list'>
>>> print(getsizeof(a))
9016
>>>
>>> b = iter(a)
>>> print(type(b))
<class 'list_iterator'>
>>> print(isinstance(b,Iterator))
True
>>> print(getsizeof(b))
48
>>> c = (i for i in range(1001))
>>> print(getsizeof(b))
48
>>> type(c)
<class 'generator'>
>>> type(b)
<class 'list_iterator'>

bはイテレーター、cはジェネレーターであり、同じメモリサイズを使用していることがわかります。

6、itertoolsをうまく活用する

itertoolsモジュールは、メモリを高速かつ効率的に使用するためのコアツールセットを標準化します。これらのツールは、単独で、または組み合わせて使用​​すると便利です。それらが一緒になって「イテレーター代数」を形成し、純粋なPythonで簡潔で効率的な特別なツールを作成することを可能にします。たとえば、文字列内の文字のすべての組み合わせ、またはリスト内の数字のすべての組み合わせが必要な場合は、次のように記述するだけで済みます。

from itertools import combinations
names = 'ABC'
for combination in combinations(names, 2):
    print(combination)
''' Output -
    ('A', 'B')
    ('A', 'C')
    ('B', 'C')
'''

これは頻繁に使用する価値のある標準ライブラリです。詳細な機能については、公式ドキュメントhttps://docs.python.org/zh-cn/3/library/itertools.html[1 ]を参照してください。

セブン、コレクションを上手に活用する

これは、使用する価値のあるもう1つの標準ライブラリコレクションです。defaultdict、OrderedDict、namedtuple、Counter、dequeなどの組み込みデータタイプを置き換える複数のコンテナを提供します。これらは、独自の実装よりも非常に便利で、はるかに安全で安定しています。といった:

# frequency of all characters in a string in sorted order
from collections import (OrderedDict, Counter)
string = 'abcbcaaba'
freq = Counter(string)
freq_sorted = OrderedDict(freq.most_common())
for key, val in freq_sorted.items():
    print(key, val)
''' Output -
    ('a', 4)
    ('b', 3)
    ('c', 2)
'''

言うまでもありませんが、公式ドキュメントを参照してください:https://docs.python.org/3/library/collections.html [2]

8.クラスを使いすぎないでください

クラスを使いすぎないでください。JavaとC ++の使用を主張するプログラマーは、クラスを使用することがよくありますが、Pythonを使用する場合は、関数とモジュールを使用してコードを再利用できます。どうしても必要な場合を除いて、クラスを作成する必要はありません。

この記事では、より優れたPythonコードを作成するための8つの方法について説明します。お役に立てば幸いです。

推奨読書:

コードをよりエレガントにするための10のヒント

プレイする価値のある6つのPythonコード

参照

[1]

https://docs.python.org/zh-cn/3/library/itertools.html:https://docs.python.org/zh-cn/3/library/itertools.html

[2]

https://docs.python.org/3/library/collections.html:https://docs.python.org/3/library/collections.html

おすすめ

転載: blog.csdn.net/somenzz/article/details/109685295