空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

Pythonのお勉強(1)

with文

コンテキストマネージャとして利用して、動作を制御することができる。(enterメソッド、exitメソッド)

以下の場合、writeメソッドの後、必ずファイルrobot.txtが閉じられる。

with open('robot.txt', 'r', encoding = 'utf8') as f:
    all_text = f.read()
    print(all_text) 

以下のように書くと、エラー処理などでファイルが閉じられない可能性があるため、上記のように書くことを推奨。

f = open('robot.txt', 'r', encoding = 'utf8')
for line in f:
    print(line , end='')
f.close()

ラムダ式

lambda 引数:命令

is_even = lambda x: x % 2 == 0
is_even(2)
-> True

引数

可変引数
  • *のときタプルになる
>>> def func(*hoge):
...   print hoge
...
>>> func("1","2","3")
('1', '2', '3')
  • **のとき辞書型になる
>>> def func(**hoge):
...   print hoge
...
>>> func(a=1,b=2,c=3)
{'a': 1, 'c': 3, 'b': 2}
>>>

イテレータ

参考;

10.1. itertools — 効率的なループ実行のためのイテレータ生成関数 — Python 3.6.5 ドキュメント

ジェネレータ

イテレータの一種

def robot_num(m):
    print("%d robot num" % m)
    while m < 5:
        if m == 4:
            print("m=4")
        yield m
        m += 1
    print("stop product robot")
    return

実行結果

In [2]: cnt = robot_num(2)

In [3]: next(cnt)
2 robot num
Out[3]: 2

In [4]: next(cnt)
Out[4]: 3

In [5]: next(cnt)
m=4
Out[5]: 4

In [6]: next(cnt)
stop product robot
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-6-77509b5792d1> in <module>()
----> 1 next(cnt)

StopIteration: 

デコレータ

関数やクラスの機能変更、拡張を行うための機構

@robot_log
def calc_add(robot1,robot2):
    return robot1+robot2

は以下と同じ

def calc_add(robot1,robot2):
    return robot1+robot2
calc_add = robot_log(calc_add)

ここで、robot_logを正しく作ると、この関数を呼ぶとlogをとるような機能を追加できる

スコープ

参考:RubyプログラマがPythonを学び始めて知ったこと10選 ④ - donghai821の日記

Pythonのクラスメンバのスコープまとめ - Qiita

Pythonメモ: privateやprotectedは

pythonにprivate変数がない件:千里の道も一歩から:So-netブログ

Python - Pythonの変数やメソッドの命名について(アンダーバー)(41277)|teratail

クロージャ

参考:Python Tips: Python でクロージャを使いたい - Life with Python

クラス継承

参考:

[Python]クラス継承(super) - Qiita

Python の super() 関数の使い方 - Life with Python

クラス属性とインスタンス属性

大事な考え方。要復習。クラスと名前空間と関連付けて整理しよう。

参考:Pythonでのクラス属性とインスタンス属性 - gogochephy’s diary

スタティックメソッド

以下のようにインスタンスに作用しないメソッド

class robot_calc(object):
    @staticmethod
    def robot_add(x,y): #selfがない
        return x+y

a = robot_calc.robot_add(1,2)

クラスメソッド

インスタンスではなくクラスそのものに作用するメソッド

class RoboVar:
    ene = 1

    @classmethod
    def full(cls, power):
        return cls.ene * power

class FullPower(RoboVar):
    ene = 2

x = FullPower.full(3) # RoboVar.full(FullPower,3) 

プライベートメンバ

  1. アンダースコアひとつ _robot → クラス内部だけで利用する
  2. アンダースコアふたつ __robot → クラス外部から参照できなくなる(厳密には_<クラス名>__<属性名>とすればアクセスできるがより安全)

Linuxコマンドを呼ぶ

#!/usr/bin/env python

import subprocess

p_test = subprocess.check_call(['ls','-a'])

参考: pythonでLinuxコマンドを実行する - ihit's diary

入出力

csv
import csv

with open('robodata.csv','r',encoding='utf8') as f:
    robodata = [k for k in csv.reader(f)]

with open('roboout.csv','w',newline='') as f:
    writer = csv.writer(f)
    writer.writerows(robodata)
pickle

以下のようにすることでオブジェクトの保存ができる

import pickle

mydata = [1,2,3]

with open('pickle_test.pickle','wb') as f: #バイナリ形式で開くこと
    pickle.dump(mydata,f)

with open('pickle_test.pickle','rb') as f:
    pic_data = pickle.load(f)

複数のオブジェクトを保存するときは以下のように記述

import pickle
import numpy as np

robo1 = np.float(28.0)
robo2 = np.array([[1.0,2.0],[3.0,4.0]])
robo3 = {'tetsujin':21, 'atom':'1000000'}

with open('pickle_test2.pickle','wb') as f: #バイナリ形式で開くこと
    pickle.dump([robo1,robo2,robo3],f)

with open('pickle_test2.pickle','rb') as f:
    [r1,r2,r3] = pickle.load(f)

print(r3['tetsujin'])

ソケット通信

  • connect : サーバーに接続
  • send : データ送信
  • sendall : すべて送りきるまで終わらない
  • settimeout : タイムアウト値を設定する
  • recv : データ受信
  • socket.timeout : exception OSErrorのサブクラス
  • socket.error : exception OSErrorの非推奨のエイリアス

参考:

スレッド

参考:

その他

  • struct.pack("i",data) : int型でdataをパックする
  • unicode() : unicodeへ変換
  • .split() : 単語を分割してリストへ
  • ~[-1] : リストの最後のもの
  • ~[0:-1] : リストの最初から最後から一つ手前まで
  • .append : リストの最後に追加
  • time.sleep : ~s待つ
  • .first()
  • .join() : 連結して一つの文字にする
  • .items() : 辞書をリストに変換
  • continue : 現在のループを終了して次のループへ

参考:

スクリプト言語コンパイル言語の違い

参考:

lint

*args **kwargs

glob