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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

3019閲覧

Google sheetsへの書き込みが途中で止まる

kamenogotoku

総合スコア16

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/08/13 01:12

ラズパイで取得したデータをGoogle sheetに書き込もうとしています。
ですが、1時間ほど書き込んだ後、必ず、

*************************
"Exception ignored in: <bound method GPIOBase.del of <gpiozero.MCP3002 object using <weakproxy at 0xb5a2aba0 to NoneType at 0x3e5780>>>
Traceback (most recent call last):
File ""/usr/lib/python3/dist-packages/gpiozero/devices.py"", line 151, in del
File ""/usr/lib/python3/dist-packages/gpiozero/spi_devices.py"", line 68, in close
ReferenceError: weakly-referenced object no longer exists
Exception ignored in: <bound method GPIOBase.del of <gpiozero.MCP3002 object using <weakproxy at 0xb5a2aba0 to NoneType at 0x3e5780>>>
Traceback (most recent call last):
File ""/usr/lib/python3/dist-packages/gpiozero/devices.py"", line 151, in del
File ""/usr/lib/python3/dist-packages/gpiozero/spi_devices.py"", line 68, in close
ReferenceError: weakly-referenced object no longer exists
"
***************************

というエラーが出て書き込みがストップします。
お心当たりのある方、このエラーの意味をご教授願えないでしょうか・・・?
またほかにいい方法があれば教えてください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

エラーの意味、は
ReferenceError: weakly-referenced object no longer exists
で検索すると色々出てくると思いますが、
「弱参照で参照していたObjectがもう無くなっている」という感じです。

通常は、誰かが参照している間はObjectは消えないのですが、弱参照という軽め?の参照のみが残っている場合は消えることがあります(Garbage Collectionされてしまう)。


■ 追記1
過去にも似たような投稿がありますね: https://teratail.com/questions/171880
解決したのかな...?

■ 追記2

エラーは MCP3002#__del__() で発生していますが、これは MCP3002 InstanceがScopeから消える時に呼び出されるので、本来無限ループしているときには起こらない気がします。
それが発生するということは、無限ループの中から抜け出す事件が起こっている(CTL+Cで止めるとか、例外が発生するとか)と思います。

ここからは大予想(完全な推測)なんですが、

    1. 1時間くらいしてspreadsheetのトークンの有効期限が切れる
    1. wks.update_cell(...) で例外発生
    1. except: pass でそれは握りつぶされる
    1. MCP3002 が後処理 (del() の呼び出し)されるときに、weakrefのエラー → 最終的なエラーはこれにみえる

という気がします。
なので、

対策1: 単に例外を握りつぶすだけの Try-Catch を削除して、他のエラーが発生している可能性を探る
対策2: それに対して対策する(時間が経過して wks.update_cell() でエラーになるなら、認証を再度実行するようなWrapperを作ったりする)

とするのが良い気がしました。

投稿2019/08/13 01:25

編集2019/08/13 02:05
mokemokechicken

総合スコア948

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

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

kamenogotoku

2019/08/13 01:29

コメント誠にありがとうございます。 何か対処法はありますでしょうか・・・?
mokemokechicken

2019/08/13 01:31

どういう状況とコードで発生したのか、質問に追記してもらえると、アドバイスできるかもしれないです。 が、過去の投稿をみるとなかなか厄介な気もします。
kamenogotoku

2019/08/13 01:47

確かに似たような質問が過去にあるのですね。 私のコードはGoogle APIへのアクセス設定後は下記です。 *********************** #書き込みスタート n = 0 if __name__ == '__main__': print("Time, Temp, Humid, Soil moisture and Nissha") try: while True: #現在時刻 dt_now = datetime.datetime.now() #温湿度データ取得 temperature,humidity = get_temp() #土壌水分データ取得 pot0 = MCP3002(channel=0) #日射データ取得 pot1 = MCP3002(channel=1) #画面出力 if temperature == 0: continue print("Time = ",dt_now) print(" Temperature = ",temperature,"C") print(" Humidity = ",humidity,"%") print(" Soil moisture = ",str(pot0.value * Vref) + "V") print(" Nissha = ",str(pot1.value * Vref) + "V") #日時情報をGoogle sheetsに書き込み d = { "dt_now" : 'Ron' } print(json.dumps(d)) # {"name": "Ron"} d['date'] = datetime.datetime.today() def myconverter(o): if isinstance(o, datetime.datetime): return o.__str__() print(json.dumps(d, default = myconverter)) # {"date": "2016-04-08 11:43:36.309721", "name": "Foo"} n = n + 1 wks.update_cell(n+1, 1, json.dumps(d, default = myconverter)) wks.update_cell(n+1, 2, temperature) wks.update_cell(n+1, 3, humidity) wks.update_cell(n+1, 4, str(pot0.value * Vref)) wks.update_cell(n+1, 5, str(pot1.value * Vref)) #指定された秒数スリープ time.sleep(100) except: pass
mokemokechicken

2019/08/13 01:54

すみません、コメント欄だとインデントが崩れてPythonのコードとしてはとても読みにくいので、 質問欄に バッククオート3つ ``` で囲む形で書いていただけないでしょうか。 ※ markdown記法では、コードをやエラーログなどを書くときは常にそうすると良いです ------------ ↓ こんな感じで ``` ここにコードを貼る ```
kamenogotoku

2019/08/13 02:14

mokemokechickenさん アドバイス誠にありがとうございます。 いいヒントがいただけたような気がしますので、見直してまた、リプライします。 コードの貼り付けもすみません、以前も指摘されたような気がします。あとでやってみます。 しばしお時間ください。 本当にありがとうございます!
guest

0

mokemokechickenさん
いろいろやった結果ですが、Google APIの読み書き込み制限、と思われます。
https://developers.google.com/analytics/devguides/reporting/core/v3/limits-quotas?hl=ja
https://tanuhack.com/python/operate-spreadsheet/
たぬはっくさんのページがAPI設定で非常にわかりやすかったのですが、読み書き込み制限を見落としていました。

アドバイスいただいたおかげで、要因を分離してエラーメッセージをつらつら眺め、分析することができました。ほんとうにありがとうございました。
いま書き込み頻度を下げて何時間までいけるかみています。

投稿2019/08/13 15:40

編集2019/08/13 15:42
kamenogotoku

総合スコア16

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

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

kamenogotoku

2019/08/15 09:01

mokemokechickenさん APIエラーの根源をみつけるべく、再度Googlesheets APIの設定をし直してみました。たぬハックさんのページhttps://tanuhack.com/python/operate-spreadsheet/は非常に有益で設定ができましたが、このなかの黒バックに書かれたコードの中に「#2つのAPIを記述しないとリフレッシュトークンを3600秒毎に発行し続けなければならない scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']」とありました。mokemokechickenさんのおかげでいろいろ切り分け検証進められてよかったのですが、もう一度、あ「アクセストークン3600秒制約解消できないでしょうか」と質問してみます。いろいろご助力いただきながら申し訳ないです。もう一度質問アップさせてください。
mokemokechicken

2019/08/15 09:40

原因究明が進んでよかったです。 たぶん、アクセストークンが3600秒で expired するのは、何をどうしても避けられないと思います。 Expireしたら、もう一度同じ認証の処理をしたら良いと思います(refresh token とかを使う方法があるかもしれませんが、今回はそもそも同じ認証処理ができるので、それで良いという気がします)。 また、質問があれば、回答できる範囲で回答させていただきます。
kamenogotoku

2019/08/15 16:47

お世話になっています。 苦戦しています。forで繰り返しながら、ある回数書き込んだら(1分に1回なら50回ほど)認証に戻るとか、考えましたが、スプレッドシートに途切れなく時系列で書き込むのはなかなか・・・・https://teratail.com/questions/190677も私にはピンとこずでして・・・python初心者としてはタフでした。あとで新しいスレッド、サンプルコード付きで投稿します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問