Python入門 簡単な読み書き、csv,pathlib,glob,shutil によるファイル操作

#はじめに
pythonで学習している際にで何度もpythonのドキュメントだったり、webで検索するのが面倒だったのでよく使うものをメモ書き程度に書いて見ました。
[pythonのドキュメント](https://docs.python.org/ja/3/tutorial/inputoutput.html)を参考にしながら以下まとめて見ました。
#ファイル操作
##書き込み
```python:
s = 'hello world'
with open('text.txt', 'w') as f:
    f.write(s)
```
##読み込み

```python:
t = "
python
Ruby
Java
go
"
with open('text.txt', 'r') as f:
    print((f.read()))
```
ここでのtはファイルに書き込まれている文字列であり、出力結果はファイルに書かれている文字列である。

```python:
with open('text.txt', 'r') as f:
    while True:
        line = f.readline()
        print(line, end='')
        if not line:
            break
```
f.readline()はファイルから１行だけ読み出すのでwhileループと用いることでファイルを１行ごとに処理を行える。printに引数(end='')を与えている理由は、readlineは改行まで含んで表示されるため。以下はprint(line,end='')ではなくprint(line)に変更した時の実行結果です。

```text:実行結果
python

Ruby

Java

go
```
##chunkで読み込む文字を指定

```python:
with open('text.txt', 'r') as f:
    while True:
        chunk = 2
        line = f.read(chunk)
        print(line)
        if not line:
            break
```
readに引数int型を与えると読み込む文字数を指定できる。

###ファイルオブジェクトのメソッド
####f.tell()

> ファイル中における現在の位置を示す整数を返す。ファイル中の現在の位置は、バイナリモードではファイルの先頭からのバイト数で、テキストモードでは不明瞭な値で表されます。

####f.seek()
> ファイル位置は基準点にオフセット値 offset を足して計算されます。参照点は from_what 引数で選びます。from_what の値が 0 ならばファイルの 先頭から測り、1 ならば現在のファイル位置を使い、2 ならばファイルの終端を参照点として使います。from_what は省略することができ、デフォルトの値は 0、すなわち参照点としてファイルの先頭を使います。

この関数の引数は今いる場所からその数だけ移動させる。例えば上記のtextファイルを読み込む場合、今いる場所が0の時seek(3)を実行することでpython文字列のpからhまで移動することになる。


```python:
with open('text.txt', 'r') as f:
    print(f.tell())
    print(f.read(1))
    f.seek(5)
    print(f.read(1))
```
```text:実行結果
0
p
n
```
##ファイル入出力するオプション
| Left align       |       Right align | 
|:-----------------|:------------------|
|r             |        読み込みのみ |   
|w           |           書き込みのみ |    
|a             |             ファイルの末尾に追加 |      
|r+               |               読み取りと書き込み |              
|w+             |            書き込みと読み込み |     
|a+          |           ファイルを読み書き用に開いて、ファイルの末尾に追加 |
|b           |      ファイルをバイナリモードで開く             |                     

```python:
with open('text.txt', 'w+') as f:
    f.write(s)
    f.seek(0)
    print(f.read())
```
```python
with open('text.txt', 'r+') as f:
    print(f.read())
    f.seek(0)
    f.write(s)
```
'r+'や'w+'は読み込みと書き込みをわざわざファイルを二回開かずに一回のオープンで可能にする。
読み込んだり書き込んだりする時実行後は最後の位置にいるのでseek(0)で戻ってあげる必要がある。

```python
import string

with open('templates/template.txt') as f:
    t = string.Template(f.read())

contents = t.substitute(name='Mike', contents='Teacher')
print(contents)
```
```text:templates/template.txt
My name is $name.

My Occupation is $contents.
```
```text:実行結果
My name is Mike.

My Occupation is Teacher.
```
string.Templateにファイルのreadを渡すことで単純な文字列置換をすることができる。置換の対象となる文字は文字列の先頭に$が付いている文字列である。substituteで文字列置換を行う。
##csvファイルへの書き込みと読み込み
```python
import csv

with open('test.csv', 'w') as csv_file:
    fieldnames = ['Item', 'Price']
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerow({'Item': 'Apple', 'Price': 100})
    writer.writerow({'Item': 'Banana', 'Price': 50})

```
csvファイルへの書き込みはDictWriterクラスにファイルとfieldnameを指定する。このDictWriterは今まで扱ってきた通常のファイルのように扱う。

```python
with open('test.csv', 'r') as csv_file:
    reader = csv.DictReader(csv_file)
    for row in reader:
        print(row['Item'], row['Price'])

```
DictReaderで読み込むファイルを指定し、csvファイルデータを表示する場合は１行ずつディクショナリーのように扱う。

##os, pathlib, glob, shutilモジュールによるファイル操作
```python 
print(os.path.exists('text.txt'))
print(os.path.isfile('text.txt'))
print(os.path.isdir('text.txt'))
```
existsはpathが実在するパスか調べ存在すればTrueを返す。
isfileやisdirはpathがファイルかディレクトリなのかを調べそうであればTrueを返す。

```python
os.rename('text.txt', 'renamed.txt')
os.symlink('renamed.txt', 'symlink.txt')
```
renameは第一引数に名前を変えるファイル、第二引数に新しいファイル名を指定することでファイルの名前を変える。
symlinkは引数のファイルどうしを同期させる関数。同じことを書き込みたいが、別々にファイルを扱う時に使われる。

```python 
os.mkdir('dir')
os.rmdir('dir')
```
ディレクトリの作成を削除。

```python
pathlib.Path('text.txt').touch()
os.remove('text.txt')
```
touch関数は与えられたパスに空のファイルを作成する。

```python
os.mkdir('dir')
os.mkdir('dir/dir2')
print(os.listdir('dir'))
```
```text:実行結果
['dir2']
```
listdirは与えられたディレクトリに含まれるディレクトリを階層的にリストで表示する。

```python
pathlib.Path('dir/dir2/text.txt').touch()
shutil.copy('dir/dir2/text.txt', 'dir/dir2/text2.txt')
print(glob.glob('dir/dir2/*'))
print(glob.glob('dir/dir2/*.txt))
```
```text:実行結果
['dir/dir2/text2.txt', 'dir/dir2/text.txt']
```
shutil.copyは第一引数のパスを第二引数のパスにコピーする。glob.globは与えられたパスにマッチするパス名を表示する。*で全てのファイルを選択可能。また*.txtのようにテキストファイルだけ取り出すような検索も可能。


```python
shutil.rmtree('test_dir')
```
rmtreeは指定されたディレクトリを削除するので、間違って大事なディレクトリを削除してしまうとそのディレクトリに含まれる全てのファイルが削除されるので気をつける。

```python
print(os.getcwd())
```
自分が今いる階層を返してくれる。