質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

3回答

1682閲覧

python class NameErrorについて

hatanakapeter

総合スコア4

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/02/26 04:27

前提・実現したいこと

pythonでTcp通信を行うための勉強をしています。
仕様としては、クライアント側から文字列を入力していって、eyeやearなどの文字列が入力されたらそのフラグをたて、フラグの数が2個たったらあるイベントフラグをたてる感じです。(aware関数をただしく定義したいです。)
しかし、私はまだclassの概念が完全に理解していないのが根本にあるのですが、原因を教えてください。

発生している問題・エラーメッセージ

Traceback (most recent call last): File "KeepAliveTcpServer.py", line 14, in <module> class EchoHandler(SocketServer.StreamRequestHandler): File "KeepAliveTcpServer.py", line 21, in EchoHandler self.eye_flg = False NameError: name 'self' is not defined

該当のソースコード

こちらはサーバー側(質問箇所)

python

1import socketserver as SocketServer 2#import redis 3 4import os 5import sys 6 7PORT = 8090 8 9 10class EchoHandler(SocketServer.StreamRequestHandler): 11 12 recv = True 13 dictdata = {} 14 15 #ブール値の各種初期化 16 self.eye_flg = False 17 self.ear_flg = False 18 self.body_flg = False 19 self.text_flg = False 20 #目や耳などの情報が複数入ってきたらイベントフラグを立てて実行する 21 self.event_flg = False 22 23 def setup(self): 24 # handle()メソッドより前に呼び出され、何らかの必要な初期化処理をする。 25 print ("connect from:", self.client_address) 26 27 def eye(self): 28 print("eye") 29 self.eye_flg = True 30 def ear(self): 31 print("ear") 32 self.ear_flg = True 33 def body(self): 34 print("body") 35 self.body_flg = True 36 def text(self): 37 print("text") 38 self.text_flg = True 39 40 #文章を作成する。 41 def createPrease(): 42 #ここで入力された目や耳のテキストデータを何かしらの文書生成のモジュールを使う。 43 print("") 44 45 46 47 ###イベントフラグ関数 48 def aware(self,eye_flg,ear_flg,body_flg,text_flg): 49 50 #目、耳2つに情報として入力されていたらイベントハンドラのフラグを立てて実行する。 51 if((self.eye_flg and self.ear_flg)): 52 self.event_flg = True 53 54 if(self.event_flg): 55 print("event appered!") 56 #ここ機能を追加していく。 57 #いったんフラグが立ったらevent_flgはFalseに戻しておく 58 self.event_flg = False 59 60 61 62 def handle(self): 63 # クライアントからの要求を実現するために必要な全ての作業をする。 64 65 # send 66 while True: 67 rcv_message = self.request.recv(8192) 68 69 if len(rcv_message) == 0: 70 break 71 if rcv_message == "eye".encode(): 72 self.eye() 73 if rcv_message == "ear".encode(): 74 self.ear() 75 if rcv_message == "body".encode(): 76 self.body() 77 if rcv_message == "text".encode(): 78 self.text() 79 80 print(rcv_message) 81 rcv_message = rcv_message.decode("utf-8") 82 print("received message : " + rcv_message) 83 84 # ここで何かの処理を加える。 85 self.aware(eye_flg,ear_flg,body_flg,text_flg) 86 87 88 89 self.request.send(rcv_message.encode('utf-8')) 90 91 # clean up 92 self.request.close() 93 94 95 def finish(self): 96 # handle()メソッドより後に呼び出され、何らかの必要なクリーンアップ処理を行う。 97 print("disconnected from:", self.client_address) 98 self.request.close() 99 100 101if __name__ == '__main__': 102 103 args = sys.argv 104 #マルチスレッド 105 server = SocketServer.ThreadingTCPServer(('', PORT), EchoHandler) 106 107 print ('listening:') 108 server.socket.getsockname() 109 server.serve_forever() 110

こちらはクライアント側(こちらは特に問題はないです。)

python

1TCP_HOST = '127.0.0.1' 2TCP_PORT = 8090 3 4import socket 5import redis 6 7import os 8import sys 9 10def input_encode(): 11 data = input("[Client] > ") 12 13 if data == "exit": 14 print ("////Finish Connect////") 15 exit() 16 17 data = data.encode('utf-8') 18 return data 19 20 21def decode(response): 22 response = response.decode() 23 24 if response == "exit": 25 print ("////Finish Connect////") 26 exit() 27 28 return response 29 30 31def main(): 32 # connection 33 args = sys.argv 34 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 35 client.settimeout(10) 36 print('HOST',TCP_HOST) 37 print('PORT',TCP_PORT) 38 r = client.connect((TCP_HOST, TCP_PORT)) 39 print ("Connect Success!! %s : %s" % (TCP_HOST, TCP_PORT)) 40 41 # send 42 while True: 43 client.send(input_encode()) 44 response = client.recv(4096) 45 response = decode(response) 46 print ("[Server] > %s " % (response)) 47 print("") 48 49 50 # clean up 51 client.close() 52 53def send(): 54 # connection open 55 args = sys.argv 56 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 57 client.settimeout(10) 58 print('HOST',TCP_HOST) 59 print('PORT',TCP_PORT) 60 r = client.connect((TCP_HOST, TCP_PORT)) 61 print ("Connect Success!! %s : %s" % (TCP_HOST, TCP_PORT)) 62 63 # send 64 #現時点ではターミナル上での標準入力で行う。 65 msg = input("input something message:") 66 print("send message :",msg) 67 client.send(msg.encode('utf-8')) 68 69 # onMessage 70 response = client.recv(4096) 71 response = decode(response) 72 print ("[Server] > %s " % (response)) 73 print("") 74 75 # conneciton close 76 client.close() 77 78 79if __name__ == '__main__': 80 #main() 81 send() 82

試したこと

最初に書いてある*_flgのブール値がクラス変数となっているからとりあえずdef __init__():を定義して以下のようにself.*と書き直したら以下のようなエラーメッセージがでました。

$ python3 KeepAliveTcpServer.py Traceback (most recent call last): File "KeepAliveTcpServer.py", line 14, in <module> class EchoHandler(SocketServer.StreamRequestHandler): File "KeepAliveTcpServer.py", line 21, in EchoHandler self.eye_flg = False NameError: name 'self' is not defined

どうすればいいのか詰んでいるので教えてください!

補足情報(FW/ツールのバージョンなど)

OS Ubuntu
python3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ソース読むとわかりやすいです。
https://github.com/python/cpython/blob/541e0ffbc85830e898b6fd712999274580f0db76/Lib/socketserver.py#L696
コンストラクタで設定しても良いですが、以下コンストラクタのソースを読むと、
コンストラクタから呼ばなくても、handleの処理ループの前で初期化しても同義になるかと思います。

python

1 def __init__(self, request, client_address, server): 2 self.request = request 3 self.client_address = client_address 4 self.server = server 5 self.setup() 6 try: 7 self.handle() 8 finally: 9 self.finish()

投稿2020/02/26 05:41

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

これってコード当たっていますか?

まず、メッセージをお読みください。

思考停止する前に、メッセージぐらいは読みましょう。

メッセージには答えが隠されています。

Traceback (most recent call last): File "KeepAliveTcpServer.py", line 14, in <module> class EchoHandler(SocketServer.StreamRequestHandler): File "KeepAliveTcpServer.py", line 21, in EchoHandler self.eye_flg = False NameError: name 'self' is not defined

私なりの訳:

トレースバック(最後に呼ばれたもの): ファイル "KeepAliveTcpServer.py" の 14行目. (= class EchoHandler(SocketServer.StreamRequestHandler): ) ファイル (同上) の 21行目 ( EchoHander ) self.eye_flg = False NameError( 名前系エラー? ): selfというものは宣言されていません

ですね。

まず、気になったのが、EchoHandler::createPreaseメソッド。
引数が無しになっています。
selfぐらいは入れるべきでは。

また、私もなんでだろ…ってしばらくggってましたが、そういや、Pythonってコンストラクタ持ってたわ。
って思いました。

参考: NameError: name 'self' is not defined, even though it is? - StackOverflow

つまり、「メソッドやコンストラクタ以外での処理は不可能」な部類なのでは。

コンストラクタを用意して、その中でself.eye_flgだのを使ってみては。

投稿2020/02/26 05:22

BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

py

1class EchoHandler(SocketServer.StreamRequestHandler): 2 3 recv = True 4 dictdata = {} 5 6 #ブール値の各種初期化 7 self.eye_flg = False 8 self.ear_flg = False 9 self.body_flg = False 10 self.text_flg = False 11 #目や耳などの情報が複数入ってきたらイベントフラグを立てて実行する 12 self.event_flg = False

ここはクラス変数定義領域で、インスタンスselfは存在していません。
def __init__(self): の初期化メソッドの中に書きましょう。

投稿2020/02/26 05:00

shiracamus

総合スコア5406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatanakapeter

2020/02/26 05:14

初期化メソッドのなかに書きました。 ```pyhton def __init__(self): #ブール値の各種初期化 self.eye_flg = False self.ear_flg = False self.body_flg = False self.text_flg = False #目や耳などの情報が複数入ってきたらイベントフラグを立てて実行する self.event_flg = False ``` これを実行するとエラーが表示されます。 ``` ---------------------------------------- Exception happened during processing of request from ('127.0.0.1', 39320) Traceback (most recent call last): File "/usr/lib/python3.5/socketserver.py", line 625, in process_request_thread self.finish_request(request, client_address) File "/usr/lib/python3.5/socketserver.py", line 354, in finish_request self.RequestHandlerClass(request, client_address, self) TypeError: __init__() takes 1 positional argument but 4 were given ---------------------------------------- ``` この4つ与えられているところがわかりません。何が与えられているのかがわかりません。
shiracamus

2020/02/26 05:49

親クラスの初期化メソッドを呼び出す必要があります。 def __init__(self, *args, **kwargs):   super().__init__(*args, **kwargs) と super を呼び出す1行を最初に書いてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問