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

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

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

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

Python

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

Q&A

解決済

2回答

1038閲覧

classのself.の要否がわからずエラーになる

lteru

総合スコア6

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2021/10/25 14:07

編集2021/10/26 01:13

前提・実現したいこと

PCのキープレスに応じて異なる音が出力されるアプリを作っています。
アプリをclassで定義しようとしたところ、initの要否が一部分からず詰まっています。
プログラミング初心者のため初歩的な質問かと存じますが、教えていただけると幸いです。

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

name 'sin_t' is not defined

該当のソースコード

Python

1# ライブラリのインポート 2import numpy as np # sin波 3import pyaudio # メモリ上の音楽を再生 4from pygame.locals import * # キープレス 5import matplotlib.pyplot as plt 6import pygame 7import sys 8 9 10# クラスの定義 11class Sinwave_synth: 12 def __init__(self, gain=0.25, rate=44100, chunk_size=1024): 13 self.gain = gain # "A" 14 self.rate = rate # サンプリング周波数"fs":44100 15 self.chunk_size = chunk_size # 音源から1回読み込むときのデータサイズ。1024(=2の10乗) とする場合が多い 16 self.p = pyaudio.PyAudio() # pyaudioの開始 17 self.start_up() # 初期値 18 19 # 初期値 20 def start_up(self): 21 global duration # 初期値のためにglobal変数が必要 22 duration = DURATION['L4'] 23 24 # sin波の作成 25 def create_sinwave(self, duration, freq): 26 self.duration = duration 27 self.freq = freq 28 29 # 指定周波数のsin波を指定秒数生成 30 t = np.arange(0, duration * self.rate) / self.rate 31 sin_t = np.sin(2 * np.pi * freq * t) 32 envRange = np.ones(int(duration * self.rate)) # 1字配列 33 34 # グラフのプロット 35 fig = plt.figure() 36 fig_envRange = fig.add_subplot(2, 1, 1) # 2行1列の1番目(1,1)に表示 37 fig_wave = fig.add_subplot(2, 1, 2) # 2行1列の2番目(2,1)に表示 38 fig_envRange.plot(t, envRange) 39 fig_wave.plot(sin_t[:500]) 40 plt.show 41 42 # ストリームに渡して再生 43 def play(self): 44 self.stream = self.p.open(format=pyaudio.paFloat32, 45 channels=1, 46 rate=self.rate, 47 frames_per_buffer=self.chunk_size, 48 output=True) 49 self.stream.write(sin_t.astype(np.float32).tobytes()) 50 self.stream.close() 51 52 53# パラメータ 54bpm = 120 55DURATION = { 56 'L1': (60 / bpm * 4), # 全音符 57 'L2': (60 / bpm * 4) / 2, # 二分音符 58 'L4': (60 / bpm * 4) / 4, # 四分音符 59 'L8': (60 / bpm * 4) / 8, # 八分音符 60} 61FREQ_SCALE = { # 周波数f0のスケール 62 'ド/C4': 261.626, 63 'レ/D4': 293.665, 64 'ミ/E4': 329.628, 65} 66 67# 実装 68Sinwave = Sinwave_synth() 69 70# 画面作成 71pygame.init() # Pygameを初期化 72screen = pygame.display.set_mode((400, 330)) # 画面を作成 73pygame.display.set_caption("keyboard event") # タイトルを作成 74 75# キープレスに応じて音を変える 76while True: 77 screen.fill((0, 0, 0)) 78 for event in pygame.event.get(): 79 80 if event.type == QUIT: 81 pygame.quit() 82 sys.exit() 83 if event.type == KEYDOWN: # キーを押したとき 84 # ESCキーならスクリプトを終了 85 if event.key == K_ESCAPE: 86 pygame.quit() 87 sys.exit() 88 89 # キーに応じて周波数変化 90 if event.key == K_a: 91 freq = FREQ_SCALE['ド/C4'] 92 elif event.key == K_s: 93 freq = FREQ_SCALE['レ/D4'] 94 elif event.key == K_d: 95 freq = FREQ_SCALE['ミ/E4'] 96 else: 97 continue 98 99 # sin波の作成 および 音声出力 100 print("押されたキー = " + pygame.key.name(event.key)) 101 Sinwave.create_sinwave(duration, freq) 102 Sinwave.play() 103 104 pygame.display.update()

試したこと

上記のclass Sinwave_synthをSinwave = Sinwave_synth()で実装したあと、create_sinwave()メソッドとplay()の順に実行しているはずが、creat_sinwave()メソッドで定義しているsint_tがplay()メソッド実行時にNameErrorになります。

<エラーあり>

Python

1# クラスの定義 2class Sinwave_synth: 34 # sin波の作成 5 def create_sinwave(self, duration, freq): 6 self.duration = duration 7 self.freq = freq 8 9 # 指定周波数のsin波を指定秒数生成 10 t = np.arange(0, duration * self.rate) / self.rate 11 sin_t = np.sin(2 * np.pi * freq * t) 12 envRange = np.ones(int(duration * self.rate)) # 1字配列 13 14 # グラフのプロット 15 fig = plt.figure() 16 fig_envRange = fig.add_subplot(2, 1, 1) # 2行1列の1番目(1,1)に表示 17 fig_wave = fig.add_subplot(2, 1, 2) # 2行1列の2番目(2,1)に表示 18 fig_envRange.plot(t, envRange) 19 fig_wave.plot(sin_t[:500]) 20 plt.show 21 22 # ストリームに渡して再生 23 def play(self): 24 self.stream = self.p.open(format=pyaudio.paFloat32, 25 channels=1, 26 rate=self.rate, 27 frames_per_buffer=self.chunk_size, 28 output=True) 29 self.stream.write(sin_t.astype(np.float32).tobytes()) 30 self.stream.close() 31

一方、create_sinwave()内のtやsin_tに"self."をつけるとエラーが無くなりました。ここで、sin_tはcreate_sinwave()のアトリビュートではない認識なのですが、なぜ"self."が必要なのでしょうか?

この"self."が必要な場合とそうでない場合がよくわかりません。グローバル変数を用いるようになると更にわからなくなります。

<エラーなし>

Python

1 2 # sin波の作成 3 def create_sinwave(self, duration, freq): 4 self.duration = duration 5 self.freq = freq 6 7 # 指定周波数のsin波を指定秒数生成 8 self.t = np.arange(0, duration * self.rate) / self.rate 9 self.sin_t = np.sin(2 * np.pi * freq * self.t) 10 self.envRange = np.ones(int(duration * self.rate)) # 1字配列 11 12 # グラフのプロット 13 fig = plt.figure() 14 fig_envRange = fig.add_subplot(2, 1, 1) # 2行1列の1番目(1,1)に表示 15 fig_wave = fig.add_subplot(2, 1, 2) # 2行1列の2番目(2,1)に表示 16 fig_envRange.plot(self.t, self.envRange) 17 fig_wave.plot(self.sin_t[:500]) 18 plt.show 19 20 # ストリームに渡して再生 21 def play(self): 22 self.stream = self.p.open(format=pyaudio.paFloat32, 23 channels=1, 24 rate=self.rate, 25 frames_per_buffer=self.chunk_size, 26 output=True) 27 self.stream.write(self.sin_t.astype(np.float32).tobytes()) 28 self.stream.close()

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

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

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

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

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

guest

回答2

0

ベストアンサー

creat_sinwave()メソッドで定義しているsint_tがplay()メソッド実行時にNameErrorになります。

self.がなければcreat_sinwave()内のtsin_tはローカル変数です。
当然play()内では使えません。

一方、create_sinwave()内のtやsin_tに"self."をつけるとエラーが無くなりました。ここで、sin_tはcreate_sinwave()のアトリビュートではない認識なのですが、なぜ"self."が必要なのでしょうか?

self.がなければcreat_sinwave()内のtsin_tはローカル変数です。

create_sinwave()内で引数selfsin_tという変数を作って代入し、
play()内で引数selfsin_tという変数を参照しています。

投稿2021/10/26 01:33

ozwk

総合スコア13521

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

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

0

公式ドキュメント チュートリアル 9.3.5. クラスとインスタンス変数を読みましょう。

あるいは公式ドキュメント Python チュートリアルを最初から読んだ方が良いかもしれません。

投稿2021/10/25 14:28

編集2021/10/25 16:00
ppaul

総合スコア24666

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問