Skip to the content.

python

インストール

python直インストール - Dockerでのamazonlinux2イメージでのpythonインストール ```Dokerfile FROM amazonlinux:2 WORKDIR /root RUN yum install -y glibc-langpack-ja && yum clean all; \ yum update -y && yum -y groupinstall "Development Tools" && \ echo "alias ll='ls -la --color'" >> /root/.bashrc; ENV LANG=ja_JP.UTF-8 \ LANGUAGE=ja_JP:ja \ LC_ALL=ja_JP.UTF-8 \ TZ=Asia/Tokyo # install python ARG PYTHON_VERSION="3.9.14" RUN yum -y install wget gcc openssl-devel bzip2-devel libffi-devel xz-devel tk-devel && \ cd /tmp/ && \ wget https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tgz && \ tar xzf Python-${PYTHON_VERSION}.tgz && \ cd Python-${PYTHON_VERSION} && \ ./configure --prefix=/opt/python/${PYTHON_VERSION}/ --enable-optimizations --with-lto --with-computed-gotos --with-system-ffi && \ make -j "$(nproc)" && \ make altinstall && \ rm /tmp/Python-${PYTHON_VERSION}.tgz && \ PYTHON_VERSION_NUNBERS=(${PYTHON_VERSION//./ }) && \ PYTHON_MAJOR=${PYTHON_VERSION_NUNBERS[0]} && \ PYTHON_MINOR=${PYTHON_VERSION_NUNBERS[1]} && \ ln -s /opt/python/${PYTHON_VERSION}/bin/python${PYTHON_MAJOR}.${PYTHON_MINOR} /opt/python/${PYTHON_VERSION}/bin/python && \ ln -s /opt/python/${PYTHON_VERSION}/bin/python${PYTHON_MAJOR}.${PYTHON_MINOR} /opt/python/${PYTHON_VERSION}/bin/python${PYTHON_MAJOR} && \ ln -s /opt/python/${PYTHON_VERSION}/bin/pip${PYTHON_MAJOR}.${PYTHON_MINOR} /opt/python/${PYTHON_VERSION}/bin/pip && \ ln -s /opt/python/${PYTHON_VERSION}/bin/pip${PYTHON_MAJOR}.${PYTHON_MINOR} /opt/python/${PYTHON_VERSION}/bin/pip${PYTHON_MAJOR} && \ ln -s /opt/python/${PYTHON_VERSION}/bin/pydoc${PYTHON_MAJOR}.${PYTHON_MINOR} /opt/python/${PYTHON_VERSION}/bin/pydoc && \ ln -s /opt/python/${PYTHON_VERSION}/bin/idle${PYTHON_MAJOR}.${PYTHON_MINOR} /opt/python/${PYTHON_VERSION}/bin/idle && \ ln -s /opt/python/${PYTHON_VERSION}/bin/python${PYTHON_MAJOR}.${PYTHON_MINOR}-config /opt/python/${PYTHON_VERSION}/bin/python-config && \ echo "PATH=/opt/python/${PYTHON_VERSION}/bin/:$PATH" >> /root/.bashrc && source /root/.bashrc && \ pip3 install boto3; ``` - [pyenv(バージョン管理パッケージ)のインストール](https://github.com/pyenv/pyenv#basic-github-checkout) ```sh # linux、bashrcを使用する場合 git clone https://github.com/pyenv/pyenv.git ~/.pyenv cd ~/.pyenv && src/configure && make -C src echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc exec "$SHELL" pyenv install 任意のバージョン pyenv global 任意のバージョン ``` - pythonのバイナリインストール(ちょっと古い3.5.9の時) ```sh wget https://www.python.org/ftp/python/3.5.9/Python-3.5.9.tar.xz tar -Jxvf Python-3.5.9.tar.xz Python-3.5.9/configure --prefix=/usr/local/python make make install rm -rf /root/* ln -s /usr/local/python/bin/python3.5 /usr/local/bin/python ln -s /usr/local/python/bin/pip3.5 /usr/local/bin/pip echo "export PATH=$PATH:/usr/local/python/bin" >> ~/.bashrc ```

環境系

# 仮想環境構築
python -m venv 仮想環境名

# 仮想環境実行
source 仮想環境名/bin/activate

# 仮想環境停止
deactivate

# 仮想環境削除
rm -rf 仮想環境名
sys.getsizeof(リストとか)

基本系

# %sは文字列埋込、%dは整数、浮動小数が%f
print('合計 %s 個です' % len(list))

# format形式
print('{} is {} years old'.format(s, i))
event.get("test", [])  # 第2引数は取得できなかった場合の値
for i in range(5):
    print(i)
# 1行で出力
for x in my_list: print(x)

# enumerate(インデックスと値を同時出力)
for i, fruit in enumerate(fruits):
  print(f"{i}: {fruit}")
# リスト
[print(i) for i in events]
event_name = [event.get("name") for event in events]

# 辞書
{key: value for i in events}
def double(n):
    return n * 3

lambda_ver = lambda n: n * 3 # doubleと同じ

print(double(3) == lambda_ver(3)) # Trueとなる
# 文字列の場合
alphabet = "ABCDEFGHIJ"
var = alphabet[:5]  # 結果: "ABCDE"

# リストの場合
list_var = [10, 20, 30, 40, 50, 60, 70]
var = list_var[:5]  # 結果: [10, 20, 30, 40, 50]
config = {
    'region_name': 'ap-northeast-1',
    'aws_access_key_id': 'dummy',
    'aws_secret_access_key': 'dummy'
}

# **configで辞書をアンパック
boto3.resource('dynamodb', **config)
# ↓これと同じ意味
boto3.resource('dynamodb', 
               region_name='ap-northeast-1',
               aws_access_key_id='dummy',
               aws_secret_access_key='dummy')
def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("処理前")
        result = func(*args, **kwargs)
        print("処理後")
        return result
    return wrapper

@my_decorator
def hello():
    print("こんにちは")

hello()

# 処理前
# こんにちは
# 処理後
# 関数の頭にasyncとつけるとawaitを使った非同期処理が使える
async def sample():
    await asyncio.sleep(1)      # 非同期で1秒待つ
    return {"message": "Async after 1s"}

実行オプション

PYTHONDONTWRITEBYTECODE=1 python スクリプト名.py

整形

# インストール
pip install flake8 autopep8

# 指定のpythonファイルがPEP8に準拠しているか確認
flake8 ファイル名.py

# 指定のpythonファイルをPEP8に準拠するようコードを修正する
autopep8 --in-place ファイル名.py
# より積極的に修正する(aggressive1回指定で中程度、複数指定でさらに強力)
autopep8 --in-place --aggressive --aggressive ファイル名.py

よく使うライブラリ

import subprocess

subprocess.run(["ls", "-l"])
subprocess.run("ls -l", shell=True)
pip install pipreqs
pipreqs .  # 現在のディレクトリに requirements.txt を自動生成

テスト系

# 全体テスト
coverage run -m unittest discover

# 個別テスト
python -m unittest -v tests/test_sample.py
coverage run -m unittest -v tests/test_sample.py

# 結果出力
coverage report -m sample.py
coverage html
import time
start = time.time()

# 処理の内容

end = time.time()
print(f"create_csvの処理時間: {end - start:.4f}秒") # .4f = 小数点下4桁まで表示

unittest

mock.assert_called()      #呼び出されたかどうかを確認
mock.assert_called_once() #呼び出されたか回数が1度だけかどうかを確認

ログ

構造

# ログの一括設定(ルートログ)
logging.basicConfig(
    level=logging.INFO,  # INFOレベル以上を出力
    format="%(asctime)s %(name)s [%(levelname)s] %(message)s"
    # デフォルトは%(levelname)s:%(name)s:%(message)s
)

# ロガー取得(引数なしならルートロガーとなる)
logger = logging.getLogger()
log_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../log'))
os.makedirs(log_dir, exist_ok=True)
log_path = os.path.join(log_dir, 'log_file_name.log')
file_handler = TimedRotatingFileHandler(
    log_path, when='midnight', interval=1, backupCount=30, encoding='utf-8', utc=False
)
file_handler.suffix = "%Y%m%d"  # ローテート後のファイル名にYYYYMMDDを付与

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s %(name)s [%(levelname)s] %(message)s"
    # ハンドラーを複数(ファイルと標準出力)設定
    handlers=[
        file_handler,
        logging.StreamHandler()
    ]
)
# ローカル出力用
logging.basicConfig(
    level=logging.INFO,  # INFOレベル以上を出力
    format="%(asctime)s [%(levelname)s] %(message)s"
)

# logging環境起動(AWS Cloudwatch書き込み用)
logger = logging.getLogger("app")

# JSTタイムゾーンのconverterを追加
formatter = logging.Formatter(
    fmt="%(asctime)s %(name)s [%(levelname)s] %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S"
)
formatter.converter = lambda *args: datetime.datetime.now(
    ZoneInfo("Asia/Tokyo")).timetuple()

# Lambdaでは既存のハンドラ(handler)があるので、全てのhandlerに適用
for handler in logger.handlers:
    handler.setFormatter(formatter)
    except Exception as error:
        import traceback
        logging.error(f"エラーが発生しました: {error}")
        logging.error(traceback.format_exc())
        raise

デバッグ

obj.__dir__()

調査

import inspect
obj = "test"
for x in inspect.getmembers(obj):
    print(x)