Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
695
Help us understand the problem. What is going on with this article?
@yinawekuky

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

More than 1 year has passed since last update.

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  #分かりにくい

num1 = 10_000_000_000  #分かりやすい

print(f'{num1:,}')
#出力結果 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・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...')
695
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yinawekuky
Python(Django) ,JS(React, Vue, D3, Gatsby)でのWebアプリ開発をやっています。 GAS, SeleniumでのRPA構築も時々やります。 座右の銘:「Happy, Kind, Crazy」

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
695
Help us understand the problem. What is going on with this article?