見出し画像

【Jaguar's Blog 4】Symbol Python New Project

この記事は2023年12月22日にNEM/Symbolのコア開発者Jaguar氏によって投稿された記事「Symbol Python New Project」をChatGPTを用いて翻訳して記事です。


Pythonはあなたの選択言語ですか?Symbol Python SDKについて夢を見ますか?Pythonプロジェクトを最大限に活用したいですか?それなら、いくつかのクイックなヒントを読んでみてください。👇


Use pyenv

私のような人は、コンピュータにたくさんのPythonプロジェクトがあるかもしれません。時折、新しいバージョンを使用する必要があるかもしれませんし、他の場合には古いバージョンを使用する必要があるかもしれません。異なるバージョンを管理するのは本当に面倒ですよね。幸いなことに、そのためのツールがあります - pyenv です。

MacOSを使用している場合、homebrewを使って簡単にpyenvをインストールできます:

brew update
brew install pyenv

正しくインストールされた場合、以下のコマンドを実行してマシン上で利用可能なすべてのPythonバージョンを確認できます:

pyenv versions

インストールされると、pyenvは1つまたは複数のインストールされたPythonバージョンを管理します。さらに良いことに、各プロジェクトごとに孤立したPython環境を使用できます!これは強くお勧めされており、プロジェクトの依存関係を管理しやすくするのに役立ちます!

新しいSymbolプロジェクト用にPython 3.11をベースにした新しい環境を作成しましょう:

pyenv virtualenv 3.11 symbol-project-1

プロジェクトディレクトリで、次のコマンドを実行してください:

pyenv local symbol-project-1

これにより、次の2つのことが実行されます:

  1. 新しく作成されたPython環境をアクティブにする

  2. symbol-project-1 Python環境が含まれるディレクトリに入ると、pyenvが自動的にアクティブになるようにする .python-version ファイルを作成します

新しいPython環境が作成されたことを確認するには、次のコマンドを実行できます:

pip list

出力には、システムのデフォルトのPythonバージョンにインストールされているすべてのパッケージとは対照的に、最小限の数のインストールされたパッケージが表示されます。

Track Requirements

pipは、-rスイッチを使用してファイルからパッケージを読み込むことができます。たとえば、次のコマンドは、requirements.txtファイルにリストされているパッケージを読み込みます:

python3 -m pip install -r requirements.txt

通常、コードで直接使用されるパッケージと、開発プロセスの一部としてのみ使用されるパッケージ(例:ビルドおよびテストの依存関係)を区別するのがベストプラクティスです。NodeJSプロジェクトで使用されるpackage.jsonファイルに精通している場合、これはdependenciesdevDependenciesによって推奨される同じ区別です。Pythonでこれをエミュレートするために、2つのrequirementsファイルを使用することをお勧めします:

  1. requirements.txt - 直接コードで使用されるパッケージ

  2. dev_requirements.txt - 開発プロセスの一部としてのみ使用されるパッケージ

Setup linter

綺麗なコードはいつも醜いコードよりも優れています。リンターは、コードベース全体で一連のベストプラクティスや共通のスタイルルールを実施しやすくするのに役立ちます。これにより、同じスタイルと慣習を使用していることを確認するため、他の人と協力するのが非常に簡単になります。完全にフォーマットされたファイルに添えられた1行の変更が届く日々は終わりますね! 😭 さらに、この強制された一貫性により、開発者は取るに足らない決定の範疇から解放され、コードの執筆や高度な問題の解決により多くのメンタルバンド幅を使えるようになります。

Symbolチームは、すべてのプロジェクトで使用される標準のPythonルールセットを微調整するのにかなりの時間を費やしました(多分、あまりにも多く)。同じルールを使用したい場合は、簡単です!

まず、このディレクトリをプロジェクト内の linters/python ディレクトリにコピーします。次に、Pythonプロジェクトまたはサブプロジェクトに scripts/ci フォルダを作成し、次の2つのスクリプトを追加します。

setup_lint.sh

このスクリプトは、単にすべてのプロジェクト依存関係(リント要件、プロジェクト要件、および開発要件)をインストールします:

#!/bin/bash

set -ex

python3 -m pip install -r "$(git rev-parse --show-toplevel)/linters/python/lint_requirements.txt"
python3 -m pip install -r requirements.txt
python3 -m pip install -r dev_requirements.txt

lint.sh

このスクリプトは4つのリンターを実行します:

  1. shellcheck - すべてのシェルスクリプトを正確性に対してチェックします

  2. isort - Pythonのimportの順序を決定論的に強制します

  3. pycodestyle - PEP8スタイルの一部をチェックします

  4. pylint - 多くのベストプラクティスやスタイルの慣習をチェックします

これらのリンターを一緒に使用することで、非常にクリーンなコードを書くのに役立ちます。ただし、いくつかのルールは最初はあなたをイライラさせる可能性があるため、適応期間があります!ルールに従うように努めるべきですが、一部のルールを無効にすることもできます。一部のルールをチェックすることは、まったくチェックしないよりもはるかに良いです!

#!/bin/bash

set -ex
find . -type f -name "*.sh" -print0 | xargs -0 shellcheck
find . -type f -name "*.py" -print0 | PYTHONPATH=. xargs -0 python3 -m isort \
    --line-length 140 \
    --indent "  " \
    --multi-line 3 \
    --check-only
find . -type f -name "*.py" -print0 | PYTHONPATH=. xargs -0 python3 -m pycodestyle \
    --config="$(git rev-parse --show-toplevel)/linters/python/.pycodestyle"
find . -type f -name "*.py" -print0 | PYTHONPATH=. xargs -0 python3 -m pylint \
    --rcfile "$(git rev-parse --show-toplevel)/linters/python/.pylintrc" \
    --load-plugins pylint_quotes \
    --disable "${PYLINT_DISABLE_COMMANDS}"

では、すべてが正しく構成されていることを確認しましょう。以下の内容の新しいPythonファイルを追加します:

import asyncio
from symbolchain.nem.KeyPair import KeyPair
from symbolchain.CryptoTypes import PrivateKey
from symbolchain.facade.NemFacade import NemFacade

def test():
    keyPair = KeyPair(PrivateKey.random());

それからリンターを走らせます:

./scripts/ci/lint.sh

驚くかもしれませんが、この小さなコードスニペットには3つの警告があります!

  1. isortは、importが順序通りでないことを検出します

  2. pycodestyleは、誤ったセミコロンを検出します

  3. pylintは、変数keyPairはkey_pairであるべきだと検出します

これらすべてを修正した結果:

import asyncio

from symbolchain.CryptoTypes import PrivateKey
from symbolchain.facade.NemFacade import NemFacade
from symbolchain.nem.KeyPair import KeyPair


def test():
    key_pair = KeyPair(PrivateKey.random())

わずかな違いですが、それは価値があります。すでに少し見栄えが良くなりましたね!最終的には、コード全体での一貫性と清潔さを評価するようになるでしょう。私はそのように感じています!

この記事が気に入ったらサポートをしてみませんか?