for 文

単純な for 文
# range を使う (start, stop, step)
for i in range(0, 3, 1):
    print(i)
# 0
# 1
# 2

# 配列を処理
items = ['a', 'b', 'c']
for item in items:
    print(item)
# a
# b
# c

# 辞書のループ
# items 以外にも keys や values がある
d = {'a': 1, 'b': 2, 'c': 3}
for key, value in d.items():
    print(key, value)
# a 1
# b 2
# c 3
リスト内包表記
odds = [i for i in range(10) if i % 2 == 1]
print(odds)
for ループ正常終了後の処理: else
for i in range(0, 3, 1):
    print(i)
else:
    # 最後まで実行された場合に処理
    # break した場合は処理しない(たぶん例外でも処理しない)
    print('Finish!')

vscode

vscode で読み込む env の指定
{
  "python.envFile": "${workspaceFolder}/.env",
}

code format

Table 1. 使用ライブラリ
項目 備考

formatter

autopep8

https://github.com/hhatto/autopep8

checker

flake8

https://gitlab.com/pycqa/flake8

インストール
# pipenv など仮想環境の使用を推奨
pip install --dev autopep8 flake8
vscode における setting.json
{
  // 保存時にフォーマットを実行
  "editor.formatOnSave": true,
  // 文字列長の最大値チェックを120に変更
  "python.linting.flake8Args": [
    "--max-line-length=120",
  ],
  // フォーマット時の文字列長の最大値を120に変更
  "python.formatting.autopep8Args": [
    "--max-line-length=120"
  ]
}

code style

キーワード引数を使うかどうか

キーワード引数 は必須ではなく、デフォルト値を持ちます。 これらは、関数に送信されるオプションのパラメータによく使用されます。 関数に2つまたは3つ以上の位置パラメータがある場合、そのシグネチャは覚えにくいため、キーワード引数をデフォルト値で使用すると便利です。 例えば、より完全な send 関数は send(message, to, cc=None, bcc=None) として定義できます。ここで、 cc と bcc はオプションで、別の値が渡されないときは None と評価されます。

— Python ヒッチハイク・ガイド - コードスタイル - 関数の引数

「関数に2つまたは3つ以上の位置パラメータがある場合」とあるので、3つ以上の引数がある場合はキーワード引数がよいのかも。

アスタリスク (*)

アスタリスク * (仮引数名アリ)
def useless_func(a, b, *args, c, d):
    pass

useless_func(1, 2, 3, 4, 5, 6)     # NG
useless_func(1, 2, 3, 4, c=5, d=6) # OK

# OK の場合は次のように割り当てられる
# a: 1
# b: 2
# args: (3, 4)
# c: 5
# d: 6
アスタリスク * (仮引数名ナシ)
# 仮引数名ナシの場合、以降(例では c, d)はキーワード引数を強制する
def useless_func(a, b, *, c, d):
    pass

useless_func(1, 2, 3, 4, c=5, d=6)  # NG
useless_func(1, 2, c=5, d=6)        # OK
# OK の場合は次のように割り当てられる
# a: 1
# b: 2
# c: 5
# d: 6
アスタリスク **
# ** はキーワード引数を辞書にまとめる
def useless_func(**kwargs):
    print(kwargs)

useless_func(a=1, b=2, c=3)
# {'a': 1, 'b': 2, 'c': 3}
ありとあらゆる引数を受け取る関数
def useless_func(*args, **kwargs):
    print(args, kwargs)

useless_func(1, 2, 3, a=1, b=2, c=3)
# (1, 2, 3) {'a': 1, 'b': 2, 'c': 3}

アンダーバー (_)

return値を無視するための_
H,W,_ = img.shape
_function(x): 関数前に1つ
def _single_leading_underscore(x):
    return n
#weak "internal use" indicator. E.g. from M import *
#does not import objects whose names start with an underscore.

基本的に外部からの参照を受け付けない,ってものにはアンダーバーを1つつけるというのがpythonの習わしのようです。

— _function(x): 関数前に1つ
__function(x): クラス名の前に2つ
def __double_leading_underscore:
     return n
#when naming a class attribute, invokes name mangling
#(inside class FooBar, __boo becomes _FooBar__boo; see below).

外部からのアクセスを受け付けませんよ対策の1つと言えるのではないかと思います。

— __function(x): クラス名の前に2つ
function(x)_: 関数後に1つ
def list_(x):
    return n
#used by convention to avoid conflicts with Python keyword

pythonの予約語をどーしても関数名に使いたい時には,後ろに1つ_つけてつかいわけろ,ということみたいです。

— function(x)_: 関数後に1つ
function(x): 関数前後に2つずつ
def __double_leading_and_trailing_underscore__:
    return n
# "magic" objects or attributes that live in user-controlled
# namespaces. E.g. __init__, __import__ or __file__. Never invent
# such names; only use them as documented.``

オブジェクトの振る舞いを変更したり,クラスの性質にあった動きをさせたい時に使うものなんだそうです。

— __function__(x): 関数前後に2つずつ

pytest

vscode における setting.json
{
  // pytest を有効化
  "python.testing.pytestEnabled": true,
}

alembic

# インストール
sudo apt install libpq-dev
pipenv install psycopg2
pipenv install --dev alembic

# 初期化
alembic init
# マイグレーションファイル生成
alembic revision -m "create users table"
# マイグレーション
alembic upgrade head
alembic upgrade +2
# マイグレーション(SQLの出力。実行はしない)
alembic upgrade ae1027a6acf --sql
# ロールバック
alembic downgrade base
alembic downgrade -1
# 現在の状態
alembic current
# 履歴表示
alembic history --verbose

データ型一覧(PostgreSQL ベース)

一部のみ。詳細はドキュメント参照。

データ型 指定値 備考

bigint

sa.BIGINT(), sa.BigInteger(), sa.dialects.postgresql.BIGINT

bit(1)

sa.dialects.postgresql.BIT

boolean

sa.BOOLEAN(), sa.Boolean(), sa.dialects.postgresql.BOOLEAN

bytea

sa.Binary(), sa.LargeBinary(), sa.PickleType(), sa.dialects.postgresql.BYTEA

character varying

sa.String(), sa.Unicode(), sa.VARCHAR(), sa.dialects.postgresql.VARCHAR

character varyingが長さ指定なしで使われた時は、いかなる長さの文字列でも受け付けます。(PostgreSQLの拡張)

character varying(256)

sa.String(256), sa.VARCHAR(256)

character varying[]

sa.ARRAY(sa.String())

character(1)

sa.CHAR(), sa.NCHAR(), sa.dialects.postgresql.CHAR

cidr

sa.dialects.postgresql.CIDR

date

sa.DATE(), sa.Date(), sa.dialects.postgresql.DATE

double precision

sa.FLOAT(), sa.Float(), sa.dialects.postgresql.FLOAT, sa.dialects.postgresql.DOUBLE_PRECISION

inet

sa.dialects.postgresql.INET

integer

sa.INT(), sa.INTEGER(), sa.Integer(), sa.dialects.postgresql.INTEGER

integer[]

sa.ARRAY(sa.Integer())

interval

sa.Interval(), sa.dialects.postgresql.INTERVAL

json

sa.JSON()

macaddr

sa.dialects.postgresql.MACADDR

money

sa.dialects.postgresql.MONEY

numeric

sa.DECIMAL(), sa.NUMERIC(), sa.Numeric(), sa.dialects.postgresql.NUMERIC

oid

sa.dialects.postgresql.OID

enum

sa.Enum(ClassName, values_callable=lambda obj: [e.value for e in obj])

real

sa.REAL(), sa.dialects.postgresql.REAL

regclass

sa.dialects.postgresql.REGCLASS

smallint

sa.SMALLINT(), sa.SmallInteger(), sa.dialects.postgresql.SMALLINT

text

sa.TEXT(), sa.Text(), sa.UnicodeText(), sa.dialects.postgresql.TEXT

いかなる長さの文字列でも格納できるtextをサポートします。 text型は標準SQLにはありませんが、多くの他のSQLデータベース管理システムも同様にサポートしています。

time without time zone

sa.TIME(), sa.Time(), sa.dialects.postgresql.TIME

timestamp with time zone

sa.DateTime(timezone=True)

timestamp with time zoneについて内部に格納されている値は常にUTCです。

timestamp without time zone

sa.DateTime(), sa.DateTime(timezone=False), sa.TIMESTAMP(), sa.dialects.postgresql.TIMESTAMP

tsvector

sa.dialects.postgresql.TSVECTOR

uuid

sa.dialects.postgresql.UUID