TypeError: __init__() missing 3 required positional arguments: 'request', になるのはなぜでしょうか
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 1,021
Pyhonのクラスに関することで細かいことになるのですが
server = HTTPServer((host, port), Handler)
正常に動作しますが
hand=Handler() にして
server = HTTPServer((host, port),hand )
に変更すると以下のようなエラー(標記)になってしまいます。
インスタンスにしてから引数にセットするとなぜエラーになるのかわかりませんので
ご教授よろしくお願いいたします。
ソースはさらに下にあります。
(python3-toku) pi@raspberrypi:~/toku1/01-04-a1/package_parts $ python app_server.py
__main__
Traceback (most recent call last):
File "app_server.py", line 147, in <module>
run(app)
File "app_server.py", line 85, in run
hand=Handler()
TypeError: __init__() missing 3 required positional arguments: 'request', 'client_address', and 'server
ソース
※の部分3点を変更
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from http.server import BaseHTTPRequestHandler, HTTPServer
import os, time
import wiringpi
from parts import Led
# グローバル変数
_application = None
_server = None
class Handler(BaseHTTPRequestHandler):
""" HTTPリクエストを処理するクラス """
def do_GET(self):
""" GETメソッドによるHTTPリクエストを処理する関数 """
global _application
if self.path == '/shutdown':
self._do_response('shutdown')
global _server
if _server is not None and _server.socket is not None:
_server.socket.close()
_server = None
return
if _application is not None:
result, response_body = _application.exec(self.path)
if result:
self._do_response(response_body)
else:
result = self._do_file_response(self.path)
if not result: # 上記にあてはまらない場合は対応するパスがない
self.send_error(404, 'File Not Found: {0}'.format(self.path))
return
def _do_response(self, s):
""" 省略 """
def _do_file_response(self, url_path):
""" 省略"""
def run(app=None, host='0.0.0.0', port=8080, cam=None):
""" サーバー起動用関数
app: アプリケーション機能拡張用オブジェクト exec()メソッドが必要
host: 待機するIPアドレス
port: 待機するポート
cam: mjpeg_server用カメラオブジェクト start(), stop(), capture() メソッドが必要
"""
global _application
global _server
_application = app
hand=Handler() ※-----ここを追加
server = HTTPServer((host, port),hand )※-------これに変更 エラーになる
#server = HTTPServer((host, port), Handler)※---これをこコメントアウト 正常
print(time.asctime(), 'Server start - {0}:{1}'.format(host, port))
try:
_server.serve_forever()
except ValueError:
print('remote shutdown')
except KeyboardInterrupt:
print('KeyboardInterrupt')
finally:
if _server is not None and _server.socket is not None:
_server.socket.close()
print(time.asctime(), 'Server stop - {0}:{1}'.format(host, port))
if __name__ == '__main__': # このファイルがスクリプトとして実行される時だけ処理を実行
print(__name__)
#run()
# -- 定数宣言 -- #
# LEDのGPIO番号
LED_PIN = 4
# HTTPレスポンス用HTMLデータ
HTML_TEXT = """
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>toku1/01</title>
</head>
<body>
<p><input type="button" value="点灯" onclick="location.href='/led/1'"></p>
<p><input type="button" value="消灯" onclick="location.href='/led/0'"></p>
<p><input type="button" value="停止" onclick="location.href='/shutdown'"></p>
</body>
</html>
"""
class Led01(Led):
""" app_server対応版parts.LEDクラス """
def exec(self, path):
""" ルーティング処理を記述 """
if path == '/led/0':
self.set_status(0) # LED消灯
elif path == '/led/1':
self.set_status(1) # LED点灯
else:
return False, ''
result_body = self.render_template()
return True, result_body
def render_template(self):
""" レンダリング処理を記述 """
return HTML_TEXT
# 自作のLED01を使ったWebアプリの実行
wiringpi.wiringPiSetup()
app = Led01(LED_PIN)
run(app)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
なぜか、というより、そもそもクラスを取る仕様なのでインスタンス化して渡すのは明確な間違いなのです。
class http.server.HTTPServer(server_address, RequestHandlerClass)¶
このクラスは TCPServer クラスの上に構築されており、サーバのアドレスをインスタンス変数 server_name および server_port に記憶します。 サーバはハンドラからアクセス可能で、通常ハンドラの server インスタンス変数からアクセスします。
http.server --- HTTP サーバ — Python 3.8.2 ドキュメント
受け取ったハンドラは内部で適切な引数でインスタンス化されます。
エラー自体は、Handler
クラスの親クラスの__init__
の定義に起因します。__init__
をオーバーライドしていないので、親クラスの定義のままです。
(オーバーライドすればいい、という意味ではありません。念の為)
class http.server.BaseHTTPRequestHandler(request, client_address, server)
http.server --- HTTP サーバ — Python 3.8.2 ドキュメント
コンストラクタは3つの引数を要求するので、hand=Handler()
を追加した時点でエラーに鳴ります。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.23%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2020/03/11 20:52
ありがとうございます!
ここまでの解決にいたるには私の知識ではたどりつけなかったです。
ドキュメントをよめるようにしたいです