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

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

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

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

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

Q&A

解決済

2回答

1004閲覧

python 別ファイルからのクラス実行について

tenn

総合スコア2

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

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

0グッド

2クリップ

投稿2023/01/07 20:56

前提

ラズパイ3でrpi-led-matrixのサンプルを改造して電光掲示板を動作させています。
他ファイルから以下ファイルのクラスを動作させることができず困っています。
selfといった仕組みが理解できていません。よろしくお願いいたします。

該当のソースコード

実行される側:runtext.py

Python

1#!/usr/bin/env python 2# Display a runtext with double-buffering. 3from samplebase import SampleBase 4from rgbmatrix import graphics 5import datetime 6import time 7 8print("test") 9 10class RunText(SampleBase): 11 def __init__(self, *args, **kwargs): 12 dt_now = datetime.datetime.now() 13 super(RunText, self).__init__(*args, **kwargs) 14 self.parser.add_argument("-t", "--text", help="The text to scroll on the RGB LED panel", default= dt_now.strftime('%H:%M')) 15 16 17 def run(self): 18 offscreen_canvas = self.matrix.CreateFrameCanvas() 19 font = graphics.Font() 20 font.LoadFont("../../../fonts/myfont.bdf") 21 textColor = graphics.Color(255, 255, 0) 22 pos = offscreen_canvas.width 23 my_text = self.args.text 24 25 #10秒経過で終了 26 t_end = time.time() + 10 27 28 while time.time() < t_end: 29 offscreen_canvas.Clear() 30 len = graphics.DrawText(offscreen_canvas, font, pos, 14, textColor, my_text) 31 32 pos -= 1 33 if (pos + len < 0): 34 pos = offscreen_canvas.width 35 36 time.sleep(0.05) 37 offscreen_canvas = self.matrix.SwapOnVSync(offscreen_canvas) 38 39 40# Main function 41if __name__ == "__main__": 42 run_text = RunText() 43 if (not run_text.process()): 44 run_text.print_help() 45

実行する側:test.py

Python

1import runtext

試したこと

  • ファイル単体での実行→class内が問題なく動作し電光掲示板に文字が流れる。print("test")も実行される
  • ファイルを別ファイルから呼び出す→print("test")のみ実行されclassは無視される

↓ここからはよく理解できず試したものになります

  • # Main functionを全て消す→単体でも動作しなくなる
  • # 権限をchmodで拡大→変化なし
  • # runtext = runtext.Runtext()をtext.pyに追加→AttributeError: module 'runtext' has no attribute 'Runtext'でエラー

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

環境:mac、raspberry pi3

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

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

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

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

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

tenn

2023/01/08 03:51

お二方ともありがとうございます。実行はできているようなのですが、書き忘れていることがありましたので追記させていただきます、申し訳ございません。 上のファイルを実行するには ``` sudo python3 runtext.py --led-rows=16 --led-no-hardware-pulse LED_NO_HARDWARE_PULSE ``` という表記が必要であり、別ファイルから実行した場合にsudoや.pyの後ろに書かれている内容が反映できていませんでした。もしこれらを反映させる手段がございましたら、そちらも教えていただけると幸いです。 やはりこちらも解決できなかったため、別で質問させていただきたいと思います。
tenn

2023/01/08 04:10

すみません、単純に sudo python3 test.py --led-rows=16 --led-no-hardware-pulse LED_NO_HARDWARE_PULSE で実行できました。
guest

回答2

0

※ 以下の説明は厳密には違う部分がありますが、簡易的な説明と思ってください。

質問の問題が起きるのは、以下で説明したことを理解していないために起きているのでしょう。長くなってしまいましたが、読んでみてください。

pythonのプラグラムファイルの使いかたにはざっくり2種類あります。

  1. そのファイルを実行して結果を得る。
  2. そのファイルをモジュールとしてインポートして使う

1の方は、なじみがあるようですが、そのファイルに書かれていることをそのまま実行することが目的のものです。
一方、2のインポートする場合は、そのファイルはクラスや関数などの機能を提供することを目的としていて、取り入れたものをどのように使うかはインポートした側がコントロールするものです。
ただ、ファイルのインポートはそのファイルの内容を実行することが目的ではないのですが、pythonの仕組みとして、そのファイルの中にその場で実行されるようなものが記述されている場合はインポートした時に実行されてしまいます。「runtext.py」をimportすると、「test」が表示されるのはそのためです。
しかし、インポートは実行が目的ではないので、本来はそのようにことが起きるのは想定していないはずです。たとえば複数回インポートしても1度しか読み込まれないので、testをもう一度表示させようとしてもう一度インポートしても、もう「test」と表示されることはありません。

このように、pythonのプログラムは、実行するための書きかたとインポートして使うための書き方が異なる言語です。

とは言っても、インポート用に作ったファイルも、簡易的な使いたいとか、テストのためなどで、そのまま実行したときの動作を定義できたほうが便利です。 また、将来的なことを考えてインポートして使えるように書いておくというのもあるでしょう。
そのような場合に使うのが、「if name == "main":」ブロックを使った動作の制御です。

このブロック内の処理は、ファイルそのものを実行した場合(1のパターン)にだけ実行されます。他のファイルからインポートしたときには実行されないのです。 便利ですね。
これは、pythonインタープリタがファイルを直接実行したときには、__name__特殊変数に__main__という文字列を設定すことを利用しています。

ということで、質問のプログラムは、

  • インポートすると、print()が実行され、RunTextクラスが使えるようになる
  • 直接実行すると、print()が実行され、RunTextクラスが定義され、"Main function"と書かれた部分の内容が実行される。

となってます。 print文は多分ちゃんとインポートされているか確認するために入れているのだと思うので、削れば、意図通りでしょう。
インポートして使う場合は、他の回答にもあるとおり、インポートした側でインスタンス化して使いましょう。

もし、Main functionと書かれた部分も機能として提供したいのであれば、この処理もmain()関数などで定義して、インポート下側で呼ぶということになるでしょう。

投稿2023/01/08 03:17

TakaiY

総合スコア12763

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

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

tenn

2023/01/08 03:54

回答ありがとうございます。 importは自分のファイルでほとんど使用したことがなかったので、このような仕組みで動いているとよく理解できていませんでした。 mainの使用方法をもう少し自分で探ってみたいと思います。
guest

0

ベストアンサー

別のファイルから任意のクラスをインポートするには、from ファイル名 import クラス名 とします。
そして、クラスをインポートした側のファイルで、クラスのインスタンスを作成します。今回の場合は、#Main function の部分です。

python

1# test.py 2from runtext import RunText 3 4# Main function 5if __name__ == "__main__": 6 run_text = RunText() 7 if (not run_text.process()): 8 run_text.print_help()

runtext.py の方の、#Main function の部分は削除しておきます。でないと 2 重に実行されてしまいます。
他の方の回答にもある通り、if __name__ == "__main__": が記載されているので削除せずとも 2 重に実行はされません。2 重に実行される可能性があるのは、print() 文だけです。
見落としてました。失礼しました。


また、ファイル単位でインポートした場合、ファイル名にドットを付けてクラスを呼び出すこともできます。

python

1import runtext 2 3run_text = runtext.RunText()

runtext = runtext.Runtext()をtext.pyに追加→AttributeError: module 'runtext' has no attribute 'Runtext'でエラー

このエラーは恐らく誤字です。クラス名が、RunText ではなく、Runtext になってます。

投稿2023/01/07 21:40

編集2023/01/09 02:14
Demerara

総合スコア397

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

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

tenn

2023/01/08 03:50

ありがとうございます、誤字には全く気がついていませんでした。 少し別の問題が発生しているのではっきりとは言えないのですが…、おそらく実行することができました!
tenn

2023/01/08 04:10

何度もすみません、問題が解決し実行が確認できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問