明日のためのプログラムその4。Pythonことはじめ。
さぁPythonですよ。
言語の習得は、自分のやってみたいものを作ってみるのが一番です。
基本から細かくとかは、リアリティがありません。
大人になってから趣味でピアノを習うとしたら、
ハノンなんかやってたら飽きちゃうだけで、
『弾きたい曲』をなんとか弾けるように!みたいにした方が長続きもするし、
結局、途中でいろんなことを学習することになるので、そういう方法のほうが良いと思うわけです。
そうですね。私の場合は今回はsocket通信が必須なので、そこらへんからやってみます。
どんな言語でも、socketなんて言ったら、bindが、、listenが 、、 recvが 、、 sendが、、
みたいにやることになるので、それでやってきましょう。
ネット上のサンプルを見ながら、ちょっと変更してやってみますね。
#https://qiita.com/__init__/items/5c89fa5b37b8c5ed32a4
#https://qiita.com/ysk24ok/items/f6e3d8f42df1b15fbd36
#-------------------------------------------------------
import socket
#-------------------------------------------------------
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('127.0.0.1', 12345))
s.listen(10)
while True:
print("--- 1 ---")
conn, addr = s.accept()
print("--- 2 ---")
with conn:
print("--- 3 ---")
while True:
print("--- 4 ---")
dat = conn.recv(1024)
print("--- 5 ---")
if not dat:
print('I beg your pardon?')
print("--- 6 ---")
break
print('dat : {}, addr: {}'.format(dat, addr))
print("--- 7 ---")
conn.sendall(b'Recv: ' + dat)
print("--- 8 ---")
#-------------------------------------------------------
で、、実行してみた結果は以下です。
本来はclient側もつくるのですが、とりあえず、、
【http://localhost:12345】
とか打てば、なんらかでるでしょ。
ってことで、、
--- 1 ---
--- 2 ---
--- 3 ---
--- 4 ---
--- 5 ---
dat : b'GET / HTTP/1.1\r\nHost: localhost:12345\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36\r\nSec-Fetch-User: ?1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: ja,en-US;q=0.9,en;q=0.8\r\nCookie: PHPSESSID=l4qdekj86k26ighu6rl2dm0kjg\r\n\r\n', addr: ('127.0.0.1', 59392)
--- 7 ---
--- 8 ---
--- 4 ---
--- 5 ---
I beg your pardon?
--- 6 ---
--- 1 ---
--- 2 ---
--- 3 ---
--- 4 ---
--- 5 ---
dat : b'GET / HTTP/1.1\r\nHost: localhost:12345\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: cross-site\r\nSec-Fetch-Mode: navigate\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: ja,en-US;q=0.9,en;q=0.8\r\nCookie: PHPSESSID=l4qdekj86k26ighu6rl2dm0kjg\r\n\r\n', addr: ('127.0.0.1', 59394)
--- 7 ---
--- 8 ---
--- 4 ---
--- 5 ---
I beg your pardon?
--- 6 ---
--- 1 ---
--- 2 ---
--- 3 ---
--- 4 ---
なんか、」まぁ、一応サーバ側として動作することは確認できましたね。
では順を追いましょう。
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
まずwithっすね。
でも、他の書き方をしてみましょう。
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
うんたしかにこれでも動きますね。
with あれこれそれ as s:
ってやつは、
s = あれこれそれ
と、とりあえずは同じ動作をしますが、どうにも前処理後処理の問題があるので、
それは『あれこれそれ』がどんなつくりかを見ないとわからないわけですね。
ということでwithに対応したclassを自分で書いてみます。
#-------------------------------------------------------
class HiraHira:
#--------------------------
def __init__(self,a,b):
self.A = a;
self.B = b;
#--------------------------
def setData(self,a,b):
self.A = a;
self.B = b;
#--------------------------
def test(self):
print("A:{} B:{}".format(self.A, self.B))
#--------------------------
def __enter__(self):
print("前処理")
return self
#--------------------------
def __exit__(self, exc_type, exc_value, traceback):
print("後処理")
#--------------------------
#-------------------------------------------------------
if __name__ == '__main__':
A = HiraHira(1,"HiraHira3HiraHira3")
print("#---------------------");
A.test();
print("#---------------------");
with HiraHira(123,"HiraHira3") as A2:
A2.test();
print("#---------------------");
そして、結果です。
#---------------------
A:1 B:HiraHira3HiraHira3
#---------------------
前処理
A:123 B:HiraHira3
後処理
#---------------------
ということで、__enter__と、__exit__が呼ばれてるのがわかります。
うんうん。
それにしても、selfというやつ、、初めて見る人にはわかりにくいかもしれませんが、
C++においてthisポインタをわたしているのをわざわざ表記している
ように見えるので、私なんかは非常にわかりやすい感じですよね(o^^o)。