目次
- 文字列操作
- 文字列結合
- インデックスとスライス
- 文字列のメソッド
- 条件文のかつ、または
- 何も入ってないとき、Noneで表す、None の判定は is を使う
- while else、for else は、 break したら else が呼ばれない。
- for 文で break
- continue だと else は呼ばれる
- range
- ループでインデックスが欲しいとき、enumerate 関数を利用
- zip関数 まとめて配列を回してくれる
- 辞書(ディクショナリー)をfor文で回す
- デフォルト引数にリスト、ディクショナリを指定すると、参照先が同じでバグの元になる
- 位置引数のタプル化
- 位置引数のタプル化でタプルを渡すとき
- ** で引数の辞書化(ディクショナリー型で受け取る)
- 引数の辞書(ディクショナリー型)に辞書(ディクショナリー型)を展開して渡す
- 関数内関数
- クロージャー
- デコレーター
- ラムダ
- ジェネレーター
- ジェネレーター 2
- リスト内包表記
- 辞書内包表記
- 集合内包表記 (Setの内包表記)
- ジェネレーター内包表記
- 名前空間とスコープ
- 例外処理
- 独自例外処理
- import と AS
- アスタリスクのインポート
- import Error の使い所
- setup.py でパッケージ化
- 組み込み関数 sorted
- 標準ライブラリ defaultdict
- ライブラリの場所、Sysパスの確認
- クラスの定義
- クラスの初期化(コンストラクタ)とクラス変数
- デストラクター
- 継承
- オーバーライドとsuperによる親のメソッド呼び出し
- プロパティーを使った属性の設定
- 抽象クラス
- 多重継承
- クラス変数
- クラスメソッドとスタティックメソッド
- 特殊メソッド
- ファイルの作成(書き込み)
- with ステートメントでファイルをopenする。
- ファイルの読み込み
- seekを使って(カーソルを)移動
- 書き込み、読み込みモード
- テンプレート
- CSVファイルの書き込み、読み込み
- ファイルの操作
- tarファイル
- zipファイル
- tempfile
- subprocess でコマンドを実行する
- datetime
文字列操作
print(r'C:\name\name') # => C:\name\name raw文字列でエスケープシーケンスを無視(無効化)
# 改行する
print("line1\nline2\nline3")
# 改行あり
print("""
line1
line2
line3
""")
# 最初と最後の改行なし
print("""\
line1
line2
line3\
""")
文字列結合
print('Hi.' * 3 + 'Mike.') # Hi.Hi.Hi.Mike.
print('aaa' + 'bbb') # => aaabbb
print('aaa''bbb') # => aaabbb
print('aaa'
'bbb') # => aaabbb
インデックスとスライス
word = 'python'
print(word[0]) # => p
print(word[1]) # => y
print(word[-1]) # => n
print(word[0:2]) # => py
print(word[:2]) # => py
print(word[2:5]) # => tho
print(word[2:]) # => thon
print('j' + word[1:]) # => jython
文字列のメソッド
s = 'My name is Mike. Hi Mike.'
print(s) # => My name is Mike. Hi Mike.
is_start = s.startswith('My')
print(is_start) # => True
print(s.find('Mike')) # => 11 最初から探して11番目にMikeあり
print(s.rfind('Mike')) # => 20 最後のを探すと20番目にMikeあり
print(s.count('Mike')) # => 2 Mikeが2つ存在する。
print(s.capitalize()) # => My name is mike. hi mike. 最初だけ大文字
print(s.title()) # => My Name Is Mike. Hi Mike. 単語の先頭が全てが大文字
print(s.upper()) # => MY NAME IS MIKE. HI MIKE. 全て大文字
print(s.lower()) # => my name is mike. hi mike. 全て小文字
print(s.replace('Mike', 'Nancy')) # => My name is Nancy. Hi Nancy. 「Mike」を「Nancy」に置換
条件文のかつ、または
`and` と `or` を利用する。
何も入ってないとき、Noneで表す、None の判定は is を使う
is_empty = None
if is_empty is None:
print('Hello')
if is_empty is not None:
print('Hello')
while else、for else は、 break したら else が呼ばれない。
count = 0
while count < 5:
if count == 4:
break
print(count)
count += 1
else:
print('done') # breakしてるから呼ばれない
for 文で break
for fruit in ['apple', 'banana', 'orange']:
if fruit == 'banana' :
break
print(fruit)
else:
print('I ate all!') # breakしてるから呼ばれない
continue だと else は呼ばれる
for fruit in ['apple', 'banana', 'orange']:
if fruit == 'banana':
continue
print(fruit)
else:
print('I ate all!') # continue だと呼ばれる。
range
# 10回ループ
for i in range(10):
print(i)
# => 0
# => 1
# => 2
# => 3
# => 4
# => 5
# => 6
# => 7
# => 8
# => 9
# 10回ループするけど5から
for i in range(5, 10):
print(i)
# => 5
# => 6
# => 7
# => 8
# => 9
# 2から10まで3こ飛ばし
for i in range(2, 10, 3):
print(i)
# => 2
# => 5
# => 8
# 変数はしようしないとき
for _ in range(10):
print('hello')
ループでインデックスが欲しいとき、enumerate 関数を利用
for i, fruit in enumerate(['apple', 'banana', 'orange']):
print(i, fruit)
# => 0 apple
# => 1 banana
# => 2 orange
zip関数 まとめて配列を回してくれる
days = ['Mon', 'Tue', 'Wen']
fruits = ['apple', 'banana', 'orange']
drinks = ['coffee', 'tea', 'beer']
for day, fruit, drink in zip(days, fruits, drinks):
print(day, fruit, drink)
# => Mon apple coffee
# => Tue banana tea
# => Wen orange beer
辞書(ディクショナリー)をfor文で回す
d = {'x': 100, 'y': 200}
print(d.items())
# => dict_items([('x', 100), ('y', 200)]) ※タプルの配列になる
for k, v in d.items():
print(k, ':', v)
# => x: 100
# => y: 200
デフォルト引数にリスト、ディクショナリを指定すると、参照先が同じでバグの元になる
def test_func(x, l=[]):
l.append(x)
return l
r = test_func(100)
print(r) # => [100]
r = test_func(100) # [100, 100]
print(r)
引数がないときはは None になるので、このように初期化してやる
def test_func(x, l=None):
if l is None:
l = []
l.append(x)
return l
r = test_func(100)
print(r) # => [100]
r = test_func(100) # [100, 100]
print(r)
位置引数のタプル化
def say_something(*args):
print(args) # => ('Hi!', 'Mike', 'Nance') タプルで取得される
say_something('Hi!', 'Mike', 'Nance')
位置引数のタプル化でタプルを渡すとき
def say_something(*args):
print(args) # => ('Hi!', 'Mike', 'Nance') タプルで取得される
t = ('Hi!', 'Mike', 'Nance')
say_something(t) # => (('Hi!', 'Mike', 'Nance'),) タブルがタブルに入ってる。
say_something(*t) # => ('Hi!', 'Mike', 'Nance') *で展開して渡す
** で引数の辞書化(ディクショナリー型で受け取る)
def menu(**kwargs):
print(kwargs) # => {'entree': 'beef', 'drink': 'coffee'}
menu(entree='beef', drink='coffee')
引数の辞書(ディクショナリー型)に辞書(ディクショナリー型)を展開して渡す
def menu(**kwargs):
print(kwargs) # => {'entree': 'beef', 'drink': 'coffee', 'dessert': 'ice'}
d = {
'entree':'beef',
'drink':'coffee',
'dessert':'ice'
}
menu(**d)
関数内関数
def outer(a, b):
def plus(c, d):
return c + d
r = plus(a, b)
print(r)
outer(1, 2)
クロージャー
def outer(a, b):
def inner():
return a + b
return inner
f = outer(1, 2) # まだ実行されない
r = f() # 実行する
print(r) # => 3
デコレーター
デコレーターを使う前
def print_info(func):
def wrapper(*args, ** kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
def add_num(a, b):
return a + b
f = print_info(add_num)
r = f(10, 20)
print(r)
デコレーターを使った後
def print_info(func):
def wrapper(*args, ** kwargs):
print('start')
result = func(*args, **kwargs)
print('end')
return result
return wrapper
@print_info
def add_num(a, b):
return a + b
f = add_num(10, 20)
print(f)
ラムダ
l = ['Mon', 'tue', 'Wed', 'Thu', 'fri', 'sat', 'Sun']
def change_words(words, func):
for word in words:
print(func(word))
def sample_func(word):
return word.capitalize()
# 通常
change_words(l, sample_func)
# ラムダで sample_func を書き換えた実装
change_words(l, lambda word: word.capitalize())
ジェネレーター
def greeting():
yield 'Good morning'
yield 'Good afternoon'
yield 'Good night'
# for g in greeting():
# print(g)
g = greeting()
print(next(g)) # Good morning
print('---')
print(next(g)) # Good afternoon
print('---')
print(next(g)) # Good night
ジェネレーター 2
def counter(num=10):
for _ in range(num):
yield 'run'
c = counter()
print(next(c))
print(next(c))
print(next(c))
print(next(c))
リスト内包表記
t = (1, 2, 3, 4, 5,)
r = []
for i in t:
if i % 2 == 0:
r.append(i)
print(r)
r = [i for i in t if i % 2 == 0]
print(r)
辞書内包表記
w = ['mon', 'tue', 'wed']
f = ['coffee', 'milk', 'water']
d = {}
for x, y in zip(w, f):
d[x] = y
print(d) # => {'mon': 'coffee', 'tue': 'milk', 'wed': 'water'}
d = {x: y for x, y in zip(w, f)}
print(d) # => {'mon': 'coffee', 'tue': 'milk', 'wed': 'water'}
集合内包表記 (Setの内包表記)
s = set()
for i in range(10):
if i % 2 == 0:
s.add(i)
print(s) # => {0, 2, 4, 6, 8}
s = {i for i in range(10) if i % 2 == 0}
print(s) # => {0, 2, 4, 6, 8}
ジェネレーター内包表記
def g():
for i in range(10):
yield i
g = g()
print(next(g)) # => 0
print(next(g)) # => 1
print(next(g)) # => 2
g = (i for i in range(10))
print(next(g)) # => 0
print(next(g)) # => 1
print(next(g)) # => 2
g = (i for i in range(10))
print(type(g)) # => <class 'generator'>
# タプルの場合は tuple をつける
g = tuple(i for i in range(10))
print(type(g)) # => <class 'tuple'>
名前空間とスコープ
animal = 'cat'
def f():
animal = 'dog'
print(globals()['animal'])
print(locals()['animal'])
f()
print(globals()) # グローバルの
print(locals()) # グローバルのローカルはグローバルと同じ
例外処理
l = [1, 2, 3]
i = 5
# NameErrorにするための例
# del l
try:
# IndexErrorにするため例
l[i]
# その他の Exception にするため
# () + 1
except IndexError as ex:
print("Don't worry: {}".format(ex))
except NameError as ex:
print(ex)
except Exception as ex:
print('other: {}', ex)
else:
print('done') # エラーがなくて成功したときだけ実行
finally:
print('clean up') # except がなくても必ず実行される
print("last")
独自例外処理
class UppercaseError(Exception):
pass
def check():
words = ["APPLE", "orange", "banana"]
for word in words:
if word.isupper():
raise UppercaseError(word)
try:
check()
except UppercaseError as ex:
print("This is my fault. Go next")
import と AS
#基本的には②でインポート
# ①
# import lesson_package.utils
# ②
from lesson_package import utils
# ③
# from lesson_package.utils import say_twice
# ①
# r = lesson_package.utils.say_twice('hello')
# ②
r = utils.say_twice('hello')
# ③
# r = say_twice("hello")
print(r)
# インポートのASはあまり利用しないほうがよい
from lesson_package import utils as u
アスタリスクのインポート
アスタリスクのインポートには、init.py の all で使う関数、変数などを記載しないと使えない。
lesson_package/lesson.py
from lesson_package.talk import *
print(animal.hoge)
lesson_package/talk/init.py
__all__ = ['animal']
import Error の使い所
古いパッケージでエラーになったら新しいのを読み込むみたいなとき、ImportError が使える。
try:
from lesson_package import utils
except ImportError:
from lesson_package.tools import utils
utils.say_twice('word')
setup.py でパッケージ化
PyCharm
- Tools -> Create setup.py で入力する。
- setup.py が作成される。
- setup.py の中で package の配列にパッケージが記載されている。
- Tools -> Run setup.py task... を押下する。
- sdist を選択する。
- dist フォルダに tar.gz のファイル(パッケージ)ができる
- *.egg-info ディレクトリにいろいろ README.md に記載したほうがいいドキュメントができている。
コマンド
- コマンドで setup.py からパッケージを作成するコマンド
% python setup.py sdist
組み込み関数 sorted
ranking = {
'B': 85,
'A': 100,
'C': 95,
}
# キーの昇順 アルファベット潤
print(sorted(ranking)) # => ['A', 'B', 'C']
# 値の昇順
print(sorted(ranking, key=ranking.get)) # => ['B', 'C', 'A']
# 値の降順
print(sorted(ranking, key=ranking.get, reverse=True)) # => ['A', 'C', 'B']
標準ライブラリ defaultdict
文字列から各文字の出現回数をカウントする処理で3パターンをの実装
s = "afaklcuslamdasfasfdasf"
d = {}
for c in s:
if c not in d:
d[c] = 0
d[c] += 1
print(d)
# => {'a': 6, 'f': 4, 'k': 1, 'l': 2, 'c': 1, 'u': 1, 's': 4, 'm': 1, 'd': 2}
d = {}
for c in s:
d.setdefault(c, 0)
d[c] += 1
print(d)
# => {'a': 6, 'f': 4, 'k': 1, 'l': 2, 'c': 1, 'u': 1, 's': 4, 'm': 1, 'd': 2}
from collections import defaultdict
d = defaultdict(int)
for c in s:
d[c] += 1
print(d)
# => defaultdict(<class 'int'>, {'a': 6, 'f': 4, 'k': 1, 'l': 2, 'c': 1, 'u': 1, 's': 4, 'm': 1, 'd': 2})
ライブラリの場所、Sysパスの確認
import termcolor # サードパーティーのパッケージ
import sys
print(termcolor.__file__)
print(sys.path)
クラスの定義
- python3 はクラスに object があってもなくてもOK、どれでもOK。
Person(object):
、Person():
、Person:
クラスの初期化(コンストラクタ)とクラス変数
- self は Java の this と同じ
- クラスメソッドには self が引数につく
class Person(object):
def __init__(self, name):
self.name = name
def say_something(self):
print("I am {}. hello ".format(self.name))
self.run(10)
def run(self, num):
print("run" * num)
person = Person("Mike")
person.say_something()
デストラクター
class Person(object):
def __init__(self, name):
self.name = name
# 使わなくなったら実行される。
def __del__(self):
print("good bye")
person = Person("Mike")
# 明示的 __del__ を呼び出す場合
del person
継承
class Car(object):
def run(self):
print("run")
class ToyotaCar(Car):
# 継承するだけでなにもしない
pass
class TeslaCar(Car):
def auto_run(self):
print("auto run")
car = Car()
car.run()
print("-------------")
toyota_car = ToyotaCar()
toyota_car.run()
print("-------------")
tesla_car = TeslaCar()
tesla_car.run()
tesla_car.auto_run()
オーバーライドとsuperによる親のメソッド呼び出し
class Car(object):
def __init__(self, model=None):
self.model = model
def run(self):
print("run")
class ToyotaCar(Car):
# オーバーライド
def run(self):
print("fast")
class TeslaCar(Car):
def __init__(self, model='Model S', enable_auto_run=False):
# ★superの__init__呼び出し
super().__init__(model)
self.enable_auto_run = enable_auto_run
# ★オーバーライド
def run(self):
print("super fast")
def auto_run(self):
print("auto run")
car = Car()
car.run()
print("-------------")
toyota_car = ToyotaCar("Lexus")
print(toyota_car.model)
toyota_car.run()
print("-------------")
tesla_car = TeslaCar("Model S")
print(tesla_car.model)
print(tesla_car.enable_auto_run)
tesla_car.run()
tesla_car.auto_run()
プロパティーを使った属性の設定
プロパティーは、先頭に_
を付ける。
def __init__(self, enable_auto_run=False):
self._enable_auto_run = enable_auto_run
getter には @property を付ける
@property
def enable_auto_run(self):
return self._enable_auto_run
setter には getter のメソッド名をアノテーションで記載する。
@enable_auto_run.setter
def enable_auto_run(self, is_enable):
self._enable_auto_run = is_enable
プロパティー__
を付けると private なプロパティになる。
self.__enable_auto_run = enable_auto_run
抽象クラス
- abc ライブラリで継承を実装する。
- 抽象メソッドには、@abc.abstractmethod を付ける
import abc
class Person(metaclass=abc.ABCMeta):
def __init__(self, age=1):
self.age = age
@abc.abstractmethod
def drive(selfs):
pass
多重継承
先に継承されたクラスのメソッドが優先される件
class Person(object):
def talk(self):
print('talk')
def run(self):
print('person run')
class Car(object):
def run(self):
print('run')
class PersonCarRobot(Person, Car): # 先にPersonが継承されているので、Personクラスの run メソッドが優先される
def fly(self):
print('talk')
person_car_robot = PersonCarRobot()
person_car_robot.talk() # => talk
person_car_robot.run() # => person run ★先に継承されたクラスのメソッドが優先される
person_car_robot.fly() # => talk
クラス変数
class Person(object):
# クラス変数
kind = 'human'
def __init__(self, name):
self.name = name
def who_are_you(self):
print(self.name, self.kind)
a = Person('A')
a.who_are_you() # => A human
b = Person('B')
b.who_are_you() # => B human
class T(object):
# クラス変数で配列を宣言
words = []
def add_word(self, word):
self.words.append(word)
c = T()
c.add_word('add 1')
c.add_word('add 2')
d = T()
d.add_word('add 3')
d.add_word('add 4')
print(c.words) # => ['add 1', 'add 2', 'add 3', 'add 4']
クラスメソッドとスタティックメソッド
class Person(object):
# クラス変数
kind = 'human'
def __init__(self):
self.x = 100
# クラスメソッド
@classmethod
def what_is_your_kind(cls):
return cls.kind
# スタティックメソッド、クラスの中になくてもOK
@staticmethod
def about():
print('about human')
a = Person()
print(a) # => <__main__.Person object at 0x100a8b2e0>
print(a.x) # => 100
print(a.kind) # => human
print(a.what_is_your_kind()) # => human
a.about() # => about human
b = Person
print(b) # => <class '__main__.Person'>
print(a.x) # => エラー インスタンスを生成してない。
print(b.kind) # => human
print(b.what_is_your_kind()) # => human
b.about() # => about human
特殊メソッド
class Word(object):
def __init__(self, text):
self.text = text
def __str__(self):
return 'Word!!!!!'
def __len__(self):
return len(self.text)
def __add__(self, word):
return self.text.lower() + word.text.lower()
def __eq__(self, word):
return self.text.lower() == word.text.lower()
w = Word('test')
print(w) # => Word!!!!!
print(len(w)) # => 4
w2 = Word('####')
print(w + w2) # => test####
print(w == w2) # => false
w3 = Word('hoge')
w4 = Word('hoge')
print(id(w3)) # => 4347419520
print(id(w4)) # => 4347419424
print(w3 == w4) # => True ※ことなるオブジェクトだが __eq__ の実装でテキストが同じだと真にするよう実装しているためTrue
ファイルの作成(書き込み)
f = open("test.txt", "w")
f.write("Text\n") # => test.txt ファイルに書き込まれる
print("My", "name", "is", "Mike", file=f) # => print でも test.txt ファイルに書き込まれる
f.close()
text.txtファイルの中身
Text
My name is Mike
with ステートメントでファイルをopenする。
with open("test.txt", "w") as f:
f.write("Text\n") # => test.txt ファイルに書き込まれる
# with ステートメントで勝手にファイルをcloseしてくれる
ファイルの読み込み
s = """\
AAA
BBB
CCC
DDD
"""
# 書き込み
with open("test.txt", "w") as f:
f.write(s) # => test.txt ファイルに書き込まれる
# 読み込み
with open("test.txt", "r") as f:
while True:
# 1行ずつ読み込む
line = f.readline()
print(line, end="")
# 2文字ずつ読み込む
chunk = 2
line = f.read(chunk)
print(line)
if not line:
break
seekを使って(カーソルを)移動
s = """\
AAA
BBB
CCC
DDD
"""
# 書き込み
with open("test.txt", "w") as f:
f.write(s) # => test.txt ファイルに書き込まれる
# 読み込み
with open("test.txt", "r") as f:
print(f.tell()) # => 0 今の場所(カーソル位置)を表示
print(f.read(1)) # => A 1文字読み込む
f.seek(5) # 5番目に移動
print(f.read(1)) # => B
書き込み、読み込みモード
s = """\
AAA
BBB
CCC
DDD
"""
# 書き込み w+ は書き込みをして、読み込み
with open("test.txt", "w+") as f:
f.write(s) # 新規にファイルが作成される
f.seek(0) # 先頭に移動する
print(f.read())
# 書き込み r+ は読み込みをして、書き込み ※ファイルが存在しないとエラー
with open("test.txt", "r+") as f:
print(f.read()) # ファイルを読み込む
f.seek(0) # 先頭に移動する
f.write(s)
テンプレート
import string
s = """\
Hi $name
$contents
Have a good day
"""
t = string.Template(s)
contents = t.substitute(name="Mike", contents="How are you?")
print(contents)
# 出力
---------
Hi Mike
How are you?
Have a good day
---------
CSVファイルの書き込み、読み込み
import csv
with open("test.csv", "w") as csv_file:
fieldnames = ["Name", "Count"]
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({"Name": "A", "Count": 1 })
writer.writerow({"Name": "B", "Count": 2})
with open("test.csv", "r") as csv_file:
reader = csv.DictReader(csv_file)
for row in reader:
print(row["Name"], row["Count"])
ファイルの操作
import glob
import os
import pathlib
import shutil
print(os.path.exists("test.txt")) # => True ファイルの存在
print(os.path.isfile("test.txt")) # => True ファイルかチェック
print(os.path.isdir("venv")) # => True ディレクトリかチェック
# ファイルの名前を変更
os.rename("test.txt", "renamed.txt")
# symlinkを貼る
os.symlink("renamed.txt", "test.txt")
os.mkdir("test_dir") # ディレクトリを作成
os.rmdir("test_dir") # ディレクトリを削除
pathlib.Path("empty.txt").touch() # 空ファイル生成
os.remove("empty.txt") # 空ファイル生成
os.mkdir("test_dir") # ディレクトリを作成
os.mkdir("test_dir/test_dir2") # さらにディレクトリを作成
print(os.listdir("test_dir")) # => ['test_dir2'] ディレクトリ確認
pathlib.Path("test_dir/test_dir2/empty.txt").touch() #空ファイル作成
shutil.copy("test_dir/test_dir2/empty.txt", "test_dir/test_dir2/empty2.txt")
print(glob.glob("test_dir/test_dir2/*")) # => ['test_dir/test_dir2/empty.txt'] ディレクトリのファイル一覧を表示
shutil.rmtree("test_dir") # ディレクトリを再起的に削除
print(os.getcwd()) # 今のディレクトリの位置
tarファイル
import tarfile
# 圧縮
with tarfile.open("test.tar.gz", "w:gz") as tr:
tr.add("test_dir")
# 展開
with tarfile.open("test.tar.gz", "r:gz") as tr:
tr.extractall(path="test_tar")
# 展開せずファイルを見る
with tr.extractfile("test_dir/sub_dir/sub_test.txt") as f:
print(f.read())
zipファイル
import glob
import zipfile
# 圧縮
with zipfile.ZipFile("test.zip", "w") as z:
# z.write("test_dir")
# z.write("test_dir/test.txt")
for f in glob.glob("test_dir/**", recursive=True):
print(f)
z.write(f)
# 展開
with zipfile.ZipFile("test.zip", "r") as z:
z.extractall(path="zzz2")
# 展開せずファイルを見る
with z.open("test_dir/test.txt") as f:
print(f.read())
tempfile
import tempfile
# tmpファイルに書き込み
with tempfile.TemporaryFile(mode="w+") as t:
t.write("hello")
t.seek(0)
print(t.read())
# tmpファイルを削除したくないとき `delete=False`にする
with tempfile.NamedTemporaryFile(delete=False) as t:
# パスの表示
print(t.name)
with open(t.name, "w+") as f:
f.write("test\n")
f.seek(0)
print(f.read())
# tmpディレクトリ
with tempfile.TemporaryDirectory() as td:
print(td)
subprocess でコマンドを実行する
import subprocess
# os.system("ls") は、最近は仕様しない subprocess を利用すること。subprocessの方が高機能
subprocess.run(["ls"]) # lsコマンドと同じ
subprocess.run(["ls", "-al"]) # lsコマンドと同じ
subprocess.run(["ls -al"], shell=True) # シェルぽく書く パイプとかを利用するとき使う
# r = subprocess.run(["lsa"], shell=True) # 存在しないコマンド
# print(r) # => /bin/sh: lsa: command not found エラーの確認
# subprocess.run(["lsa"], shell=True, check=True) # エラーをスローするときは`check=True`を付ける。
# shell=False でパイプを利用する方法
p1 = subprocess.Popen(["ls", "-al"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "test"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
output = p2.communicate()[0]
print(output)
datetime
import datetime
now = datetime.datetime.now()
print(now) # => 2024-04-22 19:01:29.954194
print(now.isoformat()) # => 2024-04-22T19:01:29.954194
print(now.strftime("%d/%m/%y-%H%M%S%f")) # => 22/04/24-190129954194
today = datetime.date.today()
print(today) # => 2024-04-22
print(today.isoformat()) # => 2024-04-22
print(today.strftime("%d/%m/%y")) # => 22/04/24
t = datetime.time(hour=1, minute=10, second=5, microsecond=100)
print(t) # => 01:10:05.000100
print(t.isoformat()) # => 01:10:05.000100
print(t.strftime("%H_%M_%S_%f")) # => 2024-04-15 19:01:29.954194
# 下記2つは同じ出力です。引いて足すか、足して引くか。
d = datetime.timedelta(weeks=-1)
print(now + d) # => 2024-04-15 19:01:29.954194
d = datetime.timedelta(weeks=+1)
print(now - d) # => 2024-04-15 19:01:29.954194