LoginSignup
587
702

More than 1 year has passed since last update.

Pythonのコードをきれいに書くコツ

Last updated at Posted at 2019-03-31

10 Python Tips and Tricks For Writing Better Codeの内容を軽く日本語でまとめました。
英語のヒアリング未熟なので、もしかしたら間違っている所があるかもしれません。

1) Ternary Conditionals:条件式

ternary operatorsとも呼ぶらしい。

condition = True

if condition:
    x = 1
else:
    x = 0

print(x)

Trueなら1を、Falseなら0を返すコードです。
このコードのif文を1行で書くと、

x = 1 if condition else 0

このように、コードをシンプルかつ分かりやすく書ける方法がないか考えることが大事です。

2) Underscore Placeholders:アンダースコアで強調させる

大きい数字が出てきたら、アンダースコア(_)で強調すると分かりやすくなります。

num1 = 10000000000  # 分かりにくい

num2 = 10_000_000_000  # 分かりやすい

print(f'{num2:,}')
# 10,000,000,000

桁数3つごとで区切って数字を分かりやすくできる。
また、printで出力する時に工夫すれば、より分かりやすくなる。

3) Context Managers:コンテキストマネージャ

コンテキストマネージャとは、
with文の実行時に、runtime context を定義するオブジェクトのことです。

runtime context とは
__enter__()呼び出しで組み立てられて、__exit__()呼び出しで取り壊される環境のこと。

コンテキストマネージャは必ず、特殊メソッドの__enter__()__exit__()を定義しないといけないらしい。

実装例 👇

f = open('test.txt','r')

file_contents = f.read()

f.close()

words = file_contents.split(' ')
word_count = len(words)
print(word_count)

上のコードの最初の3行について、with文でコンテキストマネージャを呼び出すと、

with open('test.txt','r') as f:
    file_contents = f.read()

かなり短くなる。

  • 少ないコードで可読性増す (特に例外処理の部分で高い効果を発揮する)
  • 前処理(__enter__)と、後処理(__exit__)を強制する

といったメリットがあります。

4) Enumerate : enumerate関数

names = ['Mirai','Tech','Denshi']

index = 0
for name in names:
    print(index,name)
    index += 1

よく見かけるこのようなコード。
enumerate関数を使えば、for文がとてもシンプルになります。

for index, name in enumerate(names,start=1):
    print(index, name)

5) Zip : zip関数

[ヒーロー]と、[ヒーローの名前]をリストにして表示させたいとします。
先程のenumerate関数を使って書いてみます。

names = ['Peter Parker','Clark Kent','Bruce Wayne']
heros = ['Spiderman','Superman','Batman']

for index, name in enumerate(names):
    hero = heros[index]
    print(f'{name} is actually {hero}')

実は、for文の中身で、zip文を使えば、もっと短く書けます。

for name, hero in zip (names, heros):
    print(f'{name} is actually {helo}')

このzip関数はリストが増えるほど、その効果を発揮します。
例えば、先程のリストに、[ヒーローが活躍する世界]を追加する場合は、

names = ['Peter Parker','Clark Kent','Bruce Wayne']
heros = ['Spiderman','Superman','Batman']
universes = ['Marvel','DC','DC']

for name, hero, universe in zip (names, heros, universes):
    print(f'{name} is actually {helo} from {universe}')

このように、zip関数はリストなどを簡単にまとめられます。
名前はzipファイルから来ているのでしょうか?

6) Unpacking : アンパック

アンパックとは、タプルやリストの要素を展開して複数の変数に代入することです。
様々な要素の取り出し方ができるので便利です。

アンパックの基本

# Normal
items = (1,2)
print(items)
# (1,2)

# unpaccking
a, b = (1, 2)
print(a)
print(b)
# 1
# 2

# Error!
a, b, c = (1, 2, 3, 4)
print(a)
# ValueError:too many values to unpack

変数の数と要素の数は一致する必要があります。

アンダースコア(_)を使ったアンパック

pythonでは、必要ない値を、_ に代入します。

a, _ = (1,2)
print(a)
print(_)
# 1
# 2

*を使ったアンパック

*を使えば、要素をリストとしてまとめてくれます。

x = (0, 1, 2, 3, 4)
a, b, *c = x
print(a)
print(b)
print(c)
# 0
# 1
# [2, 3, 4]

a, b*, c = x
print(a)
print(b)
print(c)
# 0
# [1, 2, 3]
# 4

こちらでもっと詳しく解説しています。

7) Setattr/Getattr : 属性の操作を分かりやすく

この関数を使えば、明示的に属性を操作でき、どんな風に設定したか分かりやすくなります。

それぞれ、「Set attribute」 「Get attribute」 の略でしょうか?

class Person():
    pass

person = Person()

first_key = 'first'
first_val = 'Bun'

# setattrを使わない場合
person.first_key = first_val
print(person.first)

# setattrを使う場合
setattr(person, first_key, first_val)
#setattr(オブジェクト,属性名,属性値)
first = getattr(person, first_key)
print(first)
# Bun

上記コードのsetattrでは、personオブジェクトの属性first_key(ここではfirst)に値first_val(ここではBun)を設定しています。
そして、getattrで、オブジェクトと属性を取得しています。

ややこしいことをしているように思いますが、どんな操作をしたのか分かりやすく、属性が増えれば増えるほど効果を発揮します。

属性が増えた時は、辞書を絡めると分かりやすくなります。

class Person():
    pass

person = Person()

person_info = {'first':'Bun', 'last':'Tarou'}

for key, value in person_info.items():
    setattr(person, key, value)

for key in person_info.keys():
    print(getattr(person, key))

# Bun
# Tarou

8) GetPass : パスワード保護

getpassを使えば、入力したパスワードを隠すことができます。
ユーザーに名前とパスワードを入力させたいとします。

username = input('Yourname: ')
password = getpass('Password: ')

print('Logging in...')

このままだと、入力する時にパスワードが丸見えになり、横からチラ見されたらやばいです。
これを防ぐために、👇のようにします。

from getpass import getpass

username = input('Yourname: ')
password = getpass('Password: ')
repassword = getPass('Again: ')

print('Logging in...')
587
702
15

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
587
702