目次

文字の利用

# 文字変数の宣言
strval="string"
strval='string'

# 文字列の連結
strval = 'str' + 'ring'   # string
strval = 'str' 'ring'     # string

# 文字列の反復
strval  = "string"
strval2 = strval*2     # stringstring

# 文字列の添字表記
strval1[0]      #'T'
strval1[0:2]    #'TE'

数値の利用

# 数値変数の宣言
intval=100

# 整数の除算は floor (実数の解を越えない最大の整数) を返す:
intval = 7/3    ※2

リストの利用

# リスト変数の定義
a = ['str1', "str2", 100, 1234]
a[0]   #str1
a[1]   #str2

# リスト内容の置換
a = ['str1', "str2", 100, 1234]
a[0:2] = [111, 222]  # a = [111,222,100,123]

# リスト数の取得
a = ['str1', "str2", 100, 1234]
len(a)   #4

タプルの利用

複数の値を ()で括るとtuple として纏める事ができる。
※これを利用して関数から複数の戻り値を返す事も可能。
※tupleの各要素へはリストと同じようにアクセス可能。

vars = ("A", "B", "C", "D")
print(vars[0])  # A

# 複数の戻り値を返す関数
def func1():
  return (100, 200)


# 複数の戻り値を受け取る
nums = func1()              # 1つの変数でtupleとして受け取る
num1, num2 = func1()   # 個別の変数で受け取る

タプルのサイズと同じ数の変数を用意すると、各要素を個別の変数で受け取る事ができる。

var1, var2, var3, var4 = ("A", "B", "C", "D")
print(var1)  # A

受取時にはリスト(*付き)変数で受け取る事も可能。

first, *more, last = ("A", "B", "C", "D")
print(first)  # A
print(last)  #  D

if文

if x < 0:
    x = 0
    print('Negative changed to zero')
elif x == 0:
    print('Zero')
elif x == 1:
    print('Single')
else:
    print('More')

for文

 list1 = ['cat', 'window', 'defenestrate']
 for x in list1:
     print(x, len(x))

# zip を使って2つのリストを処理する

names = ["Taro", "Hanako", "Ichiro"]
sexes = ["man", "woman", "man"]

for name, sex in zip(names, sexes):
    print(f'{name} is a {sex}')

pass 文

pass  # なにもしない

関数の利用

# 戻り値のない関数
def hello(x,y):
    print("hello world!")
 
# 戻り値のある関数
def add(x,y):
    return x + y

classの利用

class Sample():

    class_var1 = "class var1"  # クラス変数

    def __init__(self):
        self.instance_var1 = "instance var1"  # インスタンス変数

    @staticmethod
    def static_method():
        print("static method")

    @classmethod
    def class_method(cls):
        print("class method")
        print(f'class_var1 is "{cls.class_var1}"')

    def instance_method(self):
        print("instance method")
        print(f'instance_var1 is "{self.instance_var1}"')


# クラス変数への値のセット
Sample.class_var1 = "this is class var1!"
print(Sample.class_var1)

# インスタンス変数への値セット
obj = Sample()
obj.instance_var1 = "ABC"  # public変数として扱う
obj.instance_var2 = "DEF"  # 未定義のインスタンス変数を外から設定する事も可能
print(obj.instance_var1)
print(obj.instance_var2)
print(obj.class_var1)      # クラス変数も参照可能

# staticメソッドの呼び出し
Sample.static_method()

# インスタンスメソッドの呼び出し
obj.instance_method()

# クラスメソッドの呼び出し
Sample.class_method()

private変数はアンダーバー2つ(または1つ)で始まる変数名で定義する。
※privateメソッドも同様。

class Sample():

    def __init__(self):
        self.public_var1 = "public var1"      # publicなインスタンス変数
        self.__private_var1 = "private var1"  # privateなインスタンス変数

    def get_private_var1(self):
        return self.__private_var1


obj = Sample()
print(obj.public_var1)
print(obj.get_private_var1())
print(obj.__private_var1)       # エラー
TODO: __class__ と __dict__ について
TODO: @property @xxxx.setter @xxxx.deleter
TODO: setattr

モジュールの利用

echotest.py

def echo1():
    print("test1!")

def echo2():
    print("test2!")


# モジュールのインポート (拡張子を覗いたファイル名を指定)
import echotest

# モジュールで定義されたメソッドの利用
echotest.echo1()

# ローカルな名前に代入して利用
method1 = echotest.echo1
method1()

パッケージについて

TODO: __init__.py など

モジュール検索について

・モジュールはカレントディレクトリ、環境変数 PYTHONPATH の順に探される。
・実際には、モジュールは変数 sys.path で指定されたディレクトリのリストから検索される。

パッケージの利用

パッケージ (package) は、Python のモジュール名前空間を
``ドット付きモジュール名 (dotted module names)'' を使って構造化する手段。

モジュール検索PATHの追加

import sys,os
sys.path.append('ディレクトリ')

ファイル一覧

# coding: utf-8

import sys,os
import glob
import re

path = os.path.abspath(os.path.dirname(__file__))

# globで検索
files = glob.glob(path + "/*.md")
for file in files:
    print(file)

# os.listdirで検索
pattern = r".*\.md$"
files = os.listdir(path)
for file in files:
    match = re.match(pattern , file)
    if match:
        print(file)

呼び出し元ファイルのフルパスを取得する

呼び出し元ファイルのフルパスを取得する

import inspect

print(inspect.stack()[1].filename)

コマンドライン引数を取得する

素で書く場合は、sys.argv から取得して自分でパースする必要がある

import sys

args = sys.argv
print(args)

argparse を使用すれば楽

import argparse

parser = argparse.ArgumentParser(description='引数取得のテスト')
parser.add_argument('--max', type=int, default=30, help='最大値(デフォルト: 30)')
args = parser.parse_args()
print(f'max is {args.max}')

https://docs.python.jp/3/library/argparse.html

日付文字列を datetime オブジェクトに変換する

from datetime import datetime

date_text = '2018-01-01T01:02:03Z'
target_datetime = datetime.strptime(date_text, '%Y-%m-%dT%H:%M:%SZ')

datetime を 日付文字列に変換する

from datetime import datetime

target_datetime = datetime.now()
date_text = target_datetime.strftime('%Y-%m-%dT%H:%M:%SZ')

日付の加算

from datetime import datetime
from datetime import timedelta

target_date = datetime.now()
time_minutes = timedelta(minutes=int(minutes))
print(target_date + time_minutes)

日時を年月日単位で切り捨てる

datetime.timetuple で取得したタプルを、datetimeの引数に指定する事により、切り捨てられたdatetimeが得られる。

from datetime import datetime

def trunc_date(target_date):
    """ 
    日時を年月日単位で切り捨てる
    """
    now_date_tuple = target_date.timetuple()[:3]  # 年月日のタプルを取得
    #now_date_tuple = target_date.timetuple()[:4]  # 年月日時のタプルを取得
    #now_date_tuple = target_date.timetuple()[:5]  # 年月日時分のタプルを取得
    return datetime(*now_date_tuple)

print(trunc_date(datetime.now()))

With構文を使用して開始、終了処理を行う

__enter__ 及び __exit__ メソッドを持つクラスを with 構文と共に利用することで、開始、終了処理を行う事ができる。

sample_with.py

# coding: utf-8

class SampleWith(object):
    def __init__(self):
        print('\t with class init')

    def __enter__(self):
        # 開始処理
        print('\t with class enter')

    def __exit__(self, exc_type, exc_value, tb):
        # 終了処理
        print('\t with class exit')


if __name__ == '__main__':
    print('start')
    with SampleWith() as sample:
        print('\t\t internal start')
        for i in range(10):
            print(f'\t\t\t point {i:05d}')
        print('\t\t internal end')
    print('end')

実行結果

$python3 sample_with.py
start
	 with class init
	 with class enter
		 internal start
			 point 00000
			 point 00001
			 point 00002
			 point 00003
			 point 00004
			 point 00005
			 point 00006
			 point 00007
			 point 00008
			 point 00009
		 internal end
	 with class exit
end

リストをマージする

l1 = ['abc', 'def']
l2 = ['ghi', 'jkl']
l1.extend(l2)
print(l1)

結果

['abc', 'def', 'ghi', 'jkl']

リストをマージして別のリストを作る

l1 = ['abc', 'def']
l2 = ['ghi', 'jkl']
l3 = l1 + l2
print(l3)

結果

['abc', 'def', 'ghi', 'jkl']

dictをマージする

d1 = {'var1': 'abc', 'var2': 'def'}
d2 = {'var3': 'ghi', 'var4': 'jkl'}
d3 = {**d1, **d2}
print(d3)

結果

{'var1': 'abc', 'var2': 'def', 'var3': 'ghi', 'var4': 'jkl'}

dictのリストの各要素に値を追加/変更する

l1 = [
    {'var1': 'a1', 'var2': 'b1'},
    {'var1': 'a2', 'var2': 'b2'}
]

# 各要素にvar3を追加
l2 = [{**x, **{'var3': f'c{i+1}'}} for i, x in enumerate(l1)]
print(f'l2: {l2}')

# 各要素のvar1の値を変更
l3 = [{**x, **{'var1': f'X{i+1}'}} for i, x in enumerate(l1)]
print(f'l3: {l3}')

結果

l2: [{'var1': 'a1', 'var2': 'b1', 'var3': 'c1'}, {'var1': 'a2', 'var2': 'b2', 'var3': 'c2'}]
l3: [{'var1': 'X1', 'var2': 'b1'}, {'var1': 'X2', 'var2': 'b2'}]

リストをソートする

# 元リスト自体を変更する
l1 = [10, 1, 5, 3, 4, 6, 7]
l1.sort()
print(f'l1: {l1}')
l1.sort(reverse=True)
print(f'l1(reverse): {l1}')

# 結果を別リストに格納する
l1 = [10, 1, 5, 3, 4, 6, 7]
l2 = sorted(l1)
print(f'l2: {l2}')
l2 = sorted(l1, reverse=True)
print(f'l2(reverse): {l2}')

# dictのリストを特定のキーでソートする
from operator import itemgetter

dict_list = [
    {'var1': 1, 'var2': 4, 'var3': 'c'},
    {'var1': 4, 'var2': 2, 'var3': 'd'},
    {'var1': 2, 'var2': 3, 'var3': 'a'},
    {'var1': 3, 'var2': 1, 'var3': 'b'}
]
sorted_dict_list = sorted(dict_list, key=itemgetter('var2'))  # var2の値でソートする
print(f'sorted_dict_list: {sorted_dict_list}')

結果

l1: [1, 3, 4, 5, 6, 7, 10]
l1(reverse): [10, 7, 6, 5, 4, 3, 1]
l2: [1, 3, 4, 5, 6, 7, 10]
l2(reverse): [10, 7, 6, 5, 4, 3, 1]
sorted_dict_list: [{'var1': 3, 'var2': 1, 'var3': 'b'}, {'var1': 4, 'var2': 2, 'var3': 'd'}, {'var1': 2, 'var2': 3, 'var3': 'a'}, {'var1': 1, 'var2': 4, 'var3': 'c'}]

デコレータを使用する

無名オブジェクトを生成する

組み込み関数である type を使用して無名オブジェクトを生成する事ができる。
https://docs.python.org/ja/3/library/functions.html#type

type は引数が 1 つの場合はオブジェクトの型を返すが、引数を3つ指定すると新しい型オブジェクトを返す為、これを利用して無名オブジェクトを生成する事ができる。

obj = type('Sample', (object,), {"param1":123, "param2": 456})
obj.param1
obj.param2

結果

123
456

用途)
argparse でパースした値をそのまま引数で受け取るような関数のテストに利用できる。

YAMLを扱う

プログラムから扱う場合

PyYAMLを利用すれば json とほぼ同じIFで扱う事ができる。

https://pypi.org/project/PyYAML/
https://pyyaml.org/wiki/PyYAML

インストール

pip install pyyaml

利用方法

# coding: utf-8

import yaml

if __name__ == '__main__':
    data = { 
        'var1': 'aaa',
        'list1': [
            {'listvar1': 'test1-1', 'listvar2': 'test1-2'},
            {'listvar1': 'test2-1', 'listvar2': 'test2-2'}
        ],  
        'map1': {
            'mapvar1': 'ABC',
            'maplist2': [
                '111', '222'
            ],  
            'mapmap3': {
                'var1': 10, 
                'var2': 20
            }   
        }   
    }   
    print('##### dict -> yaml(str) #####')
    yaml_str = yaml.dump(data)
    print(yaml_str)
    print('##### yaml(str) -> dict #####')
    yaml_dict = yaml.load(yaml_str)
    print(yaml_dict)

実行結果

python index.py

##### dict -> yaml(str) #####
list1:
- {listvar1: test1-1, listvar2: test1-2}
- {listvar1: test2-1, listvar2: test2-2}
map1:
  maplist2: ['111', '222']
  mapmap3: {var1: 10, var2: 20}
  mapvar1: ABC
var1: aaa

##### yaml(str) -> dict #####
{'list1': [{'listvar1': 'test1-1', 'listvar2': 'test1-2'}, {'listvar1': 'test2-1', 'listvar2': 'test2-2'}], 'map1': {'maplist2': ['111', '222'], 'mapmap3': {'var1': 10, 'var2': 20}, 'mapvar1': 'ABC'}, 'var1': 'aaa'}

コマンドラインから扱う場合

コマンドラインから扱う場合は yq が楽。( jq ライクに扱える )
https://yq.readthedocs.io/en/latest/

インストール

pip install yq

利用方法

# 標準入力からYAMLを読み込んでJSONに変換
cat input.yml | yq .

# 標準入力からJSONを読み込んでYAMLに変換
cat input.json | yq -y .

# ファイルを指定してYAMLからJSONに変換
yq . input.yml

# ファイルを指定してJSONからYAMLに変換
yq -y . input.json

簡易Webサーバ

サーバロジックを書きたい場合は pythonでWebサーバを書いてみる を参照。

python -m http.server 8000 -b localhost

※-b を指定しない場合は、localhost 以外にも公開される。( -b 0.0.0.0 と同じ)

仮想環境

pyenv を使用する

pyenv を使用すれば pythonのバージョン切り替えを簡単に行う事ができる。

TODO:

関連: pyenvを引っこ抜いて別環境で利用できるか確認

virtualenv を使用する

プロジェクトに必要なライブラリの管理をしたい場合には virtualenv が利用できる。
※ python 3.3 以降であれば venv、それ以前であれば virtualenv コマンドで簡単に仮想環境を作成する事が可能。

仮想環境の作成(python3.2以前)

pip install virtualenv
virtualenv /path/to/my_venv

仮想環境の作成(python3.3以降)

python3 -m venv /path/to/my_venv

仮想環境を有効にする

source /path/to/my_venv/bin/activate

仮想環境を抜ける

deactivate

pipenv を使用する

pipenv を使用するとpython自体のバージョン 及び モジュール(ライブラリ)も管理できる。

インストール

pip install pipenv

バージョン切り替え

pipenv --python 3.7

※対象のバージョンがインストールされていない時は自動でインストールされる

仮想環境へのライブラリのインストール

pipenv install flask

※インストールされたライブラリは Pipfile に記録される。

仮想環境へのライブラリのインストール( Pipfile から )

pipenv install
pipenv install --dev

仮想環境へのライブラリのインストール( Pipfile.lock から )

pipenv sync
pipenv sync --dev

仮想環境へのライブラリのインストール( requirements.txt から )

pipenv install -r ./requirements.txt

仮想環境のシェルを起動する

pipenv shell

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-11-02 (金) 07:33:38 (2173d)