Brython – Timer

Brythonにおけるタイマ処理

Brthonでタイマ処理を実装する場合、time.sleep()メソッドとスレッドクラスの継承を用いても、ブラウザで適切に処理されない(Chromeで実行した場合、処理の冒頭に反応がなく、ある程度の時間後にそれまでの処理が一挙に実行され、その後正常なタイマ処理が続行された)。

Brython固有の機能としてbrowser.timerモジュールにJavaScriptのintervalやtimeoutに相当する以下のメソッド群が用意されている。

  • set_interval()/clear_interval
  • set_timeout()/clear_timeout()
  • request_animation_frame()/cancel_animation_frame

これらはJavaScriptのそれぞれに相当する関数のwrapperであり、JavaScriptの仕様に従っていると考えられる。

JavaScriptのタイマ関係の関数についてはこちらを参照。

interval

基本形

timerパッケージのset_interval()メソッドで一定時間間隔で関数を起動し、clear_interval()メソッドでタイマーの実行を停止する。

引数を渡す場合

ターゲットの関数に引数を渡したい場合、BrythonではJavaScriptのような文字列渡しはできないが、lambda関数式で無名関数の中でターゲットの関数に引数を渡すことができる。

こちらのデモにもtimer.set_interval()を利用している。

 

Brythonの実行時間

概要

Python3、JavaScriptとBrythonの実行時間を比較してみる。

数値演算

Python/Brythonコード


JavaScriptコード

結果

経過時間
Python3 0.152009sec
Brython 3.068000sec
JavaScript 3.000000sec

配列の確保

Python/Brython

JavaScript

結果

経過時間
Python3 0.006001sec
Brython 8.212000sec
JavaScript 2.000000sec

Brython – canvas

Brythonによるcanvasの利用

  1. HTMLで、canvas要素をidを付して記述
  2. browserからdocumentをインポート
  3. documentからcanvasを取得
  4. canvasが取得可能かどうか判定
  5. 2Dのcontextを取得
  6. contextに対してライブラリで描画

canvasライブラリについてはHTML5-canvasを参照。

 

Brython

Brython利用の基本形

  1. Brythonのライブラリを読み込む
  2. brython()を実行させるよう指示する
  3. scriptタグでPythonを指定する
  4. script要素内にPythonのコードを記述する

Brythonのライブラリを読み込む

ライブラリはJavascriptファイル。head要素内でライブラリを指定して読み込ませるが、サーバ上にライブラリを配置しておく方法と、その都度Brythonのサイトから読み込む方法がある。

サーバ上にライブラリを置く場合

サーバ上にライブラリを置かない場合

brython()を実行させる

通常の事例では、body要素のonload属性で指示している。

scriptタグでPythonを指定する

コード例

Brythonのコード例。テクストボックスに名前を入力し、alertで表示。

ボタンのonclick属性でhello()関数を呼び出そうとするとundefinedエラーとなる。Brythonのサイトの事例ではdocオブジェクトのbindメソッドを用いており、これで動作した。

WordPressに移行してからスクリプトの使い方がわからないので、ここではコード例のみ。

console.log

Brythonでconsole.logを使うためには、browser.consoleパッケージを利用する。


 

Python3 – 処理時間の計測

time.time()関数は、呼び出した時点のエポックタイムを秒単位の浮動小数点型で返す。


 

Python3 – スレッド

基本形

threading.Threadクラスで実行する関数と引数を指定し、start()メソッドで開始させる。

同期

幾つかのスレッドの終了を待ってから後続のスレッドを実行させたい場合、join()メソッドで同期をとりたいスレッドの終了を待機する。

スレッドクラス

スレッドクラスを継承したカスタムクラスでの実装方法。

  • thread.Threadクラスを継承する
  • コンストラクタでThreadクラスのコンストラクタを呼び、必要なプロパティをセット
  • run()メソッドをオーバーライドし、処理内容を記述
  • カスタムクラスのインスタンスでstart()を実行

start()メソッドを実行すると、親のThreadクラスのstart()メソッドが呼び出され、そこでrun()メソッドが呼ばれ、カスタムクラスでオーバーライドしたrun()メソッドが実行される。run()メソッドを直接実行すると、シングルスレッドとして実行される。

スレッドの停止

スレッド停止の機能は、thread.Threadクラスを継承したカスタムクラスで実装する。

 

Python3 – 変数のスコープ

ブロックスコープはない

したがって、if文やfor文などの制御構文はスコープを持たない。制御文の外で定義された変数は制御文内で参照でき、制御文内での変更は変数に影響を与える。

関数のスコープ

関数内では変数はローカルスコープを持つ。

  • グローバル変数は関数内から直接には参照できないため、無定義で参照しようとするとエラーとなる
  • 関数内でグローバル変数と同じ名前の変数を定義すると、ローカル変数として扱われる
  • ローカル変数の変更は、同名のグローバル変数に影響を与えない

クラスのスコープ

クラスはローカルのスコープを持つが、クラス変数とインスタンス変数でもスコープが異なる。

global宣言

グローバル変数をglobal宣言することで、関数の中で参照・変更が可能となる。

 

Python3 – クラス

クラスの定義

標準形

  • クラス定義は、class [クラス名]:で始める
  • コンストラクタ名は__init__で決まっている(前後にアンダースコア2つ)
  • クラス変数(プロパティ)はコンストラクタで定義して明示

関数定義と同じく、クラスからオブジェクトを生成するときは、クラスを定義した後でなければならない。

プロパティ

クラス変数(クラス・プロパティ)

クラス定義の直下で定義された変数はクラス変数となり、全てのインスタンスを通じて同じ値が参照される。一般的には[クラス名].[クラス変数名]で用いる。

インスタンス変数(インスタンス・プロパティ)

インスタンス変数は、コンストラクタで定義して明示する。

インスタンス生成後にプロパティを定義することもできるが、あるインスタンスで定義したプロパティはそのクラスの他のインスタンスにはいきわたらない。

なお上記のpass文は、空のクラスのための構文。クラスの構文上は何か内容が必要なため、プレースホルダとしてpass文を置いている。passはPythonの予約語で、何も行わない。

インスタンス変数はpublic

Pythonのインスタンス変数は全てpublicアクセス可能。これを隠蔽するのに、以下の方法がある。

  1. クラス変数の先頭にアンダースコアを1つ付ける(_)
    • この方法は「作法」であり、普通に変数名を指定してアクセスが可能
  2. クラス変数の先頭にアンダースコアを2つ付ける(__)
    • この方法はPythonでアクセスが拒否される

ただし(2)の方法でも実はアクセスが可能。アンダースコア2つを前置した変数は、_クラス名__変数名に変換されるため、この変数名を使ってアクセスできる。

メソッド

コンストラクタ

  • コンストラクタの名前は__init__で決まっている
  • 少なくとも先頭に1つの、自己参照用の引数が必要
    • この引数の変数名は任意だが、Pythonの慣習でselfを用いることになっている

インスタンスメソッド

コンストラクタと同じく、インスタンスメソッドは最低1つの引数を持ち、第1引数はインスタンス自身への参照が渡される。

この引数の変数名は任意だが、Pythonの慣習でselfを用いることになっている。

クラスの継承

継承

基本的なクラスの継承方法は以下の手順による。

  1. 子クラスのclass宣言で親クラスを指定
  2. 子クラスのコンストラクタで親クラスのコンストラクタを呼ぶ
  3. 必要に応じて追加のプロパティを定義

オーバーライド

子クラスで親クラスのメソッドをオーバーライドできる。

親クラスのメソッドの呼び出し

子クラスでオーバーライドしたメソッドでも、親クラスの名前を指定して、親のメソッドを呼び出せる。

※super()メソッドを用いるべきか。

 

Python3 – lambda式

概要

ラムダ式(lambda式)は、無名の小さな関数を定義する。

lambda式の用法

lambda式は式として扱われるため、以下のような用い方が可能。

リストの内包表記

 

Python3 – 関数

基本形

  • 関数の定義は”def”で始める
  • 関数名と引数の後にコロン”:”を置く
  • 関数の内容にはインデントを入れて書く

呼び出しと定義

関数の呼び出しは関数定義の後でなければならない。

ただし、関数定義においては、後で定義される関数をそれより前の関数定義で記述することはできる。

戻り値

戻り値がある場合はreturn文で返す。

複数の戻り値

複数の戻り値を返すことができる。

引数

通常の引数

通常の引数に対しては、呼び出し時にその個数分の値を指定する。個数が多すぎても少なすぎてもTypeErrorとなる。

デフォルト値付きの引数

引数を省略した場合のデフォルト値を指定できる(キーワード付き引数)。

可変長の引数(1)

*[引数名]は数を超えた引数をタプルで受け取る。

可変長の引数(2)

**[引数名]はキーワード付き引数を辞書型で受け取る。

可変長引数の引き渡し

可変長の引数を変数で引き渡す場合、引き渡し側の引数に*、**をつける。