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

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

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

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

Python

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

Q&A

0回答

1432閲覧

Cython上でインスタンス化したオブジェクトにCythonのオブジェクトを与える方法について

decoyxyz

総合スコア13

Python 3.x

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

Python

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

0グッド

0クリップ

投稿2019/11/03 16:54

実現したいこと

  1. Main.py, SubA.py, SubB.pyをそれぞれコンパイル
  2. Main.pyからSubAとSubBを呼び出し、インスタンス化
  3. SubAにSubBを与える
  4. SubAを実行し、結果をSubBのインスタンス変数から読み込みprint

データを読み込んだり、外部と通信するSubB.pyと、
特定のアルゴリズムで処理を行うSubA.pyを、
Mein.pyから呼び出しています。

用途によって渡すモジュールや処理するアルゴリズムを切り替えたいため、このような実装になっております。

純粋なPythonではうまく動きますが、処理が低速なため、Cythonを使用しようと思いましたが、エラーが発生してしまい、解決方法が分かりません・・・
オーバーヘッドを抑えつつ、エラーを解消する方法がありましたら、ご教示ください。

環境

Python 3.6.8
Cython 0.29.14
Cythonはpure Pythonモードを使用しています。

該当のソースコード

同一のディレクトリに以下のファイルがあり、コンパイル後init.pyを実行します。
init.py/Main.py/SubA.py/SubB.py/setup.py

コマンド:
python setup.py build_ext --inplace

initpy

1from Main import * 2import array 3 4Main(array.array("q", range(100)))

Mainpy

1import cython 2from SubA import * 3from SubB import * 4 5 6class Main: 7 data = cython.declare(cython.longlong[:]) 8 9 @cython.locals(data=cython.longlong[:], result=cython.longlong) 10 def __init__(self, data): 11 self.data = data 12 subB = SubB(data) 13 subA = SubA(subB) 14 subA.start() 15 result = subA.result 16 print(result)

SubApy

1import cython 2 3@cython.cclass 4class SubA: 5 result = cython.declare(cython.longlong) 6 7 def __init__(self, subB): 8 self.subB = subB 9 self.result = 0 10 11 @cython.cfunc 12 def start(self): 13 while self.subB.flag: 14 self.result += self.subB.get() 15 self.subB.add() 16

SubBpy

1import cython 2 3@cython.cclass 4class SubB: 5 data = cython.declare(cython.longlong[:]) 6 i = cython.declare(cython.int) 7 len = cython.declare(cython.int) 8 flag = cython.declare(cython.bint, visibility='public') 9 10 @cython.locals(data=cython.longlong[:]) 11 def __init__(self, data): 12 self.data = data 13 self.i = 0 14 self.len = len(data) 15 self.flag = True 16 17 @cython.cfunc 18 def add(self): 19 self.i += 1 20 if self.i >= self.len: 21 self.flag = False 22 23 @cython.cfunc 24 @cython.returns(cython.longlong) 25 def get(self): 26 if self.i >= self.len: 27 return 0 28 return self.data[self.i] 29

setuppy

1from distutils.core import setup 2from distutils.extension import Extension 3from Cython.Distutils import build_ext 4 5files = ["SubA", "SubB", "Main"] 6 7 8for f in files: 9 ext_modules = [Extension(f, [f + ".py"])] 10 11 setup( 12 name=f, 13 cmdclass={'build_ext': build_ext}, 14 ext_modules=ext_modules 15 ) 16

発生しているエラー

console

1Traceback (most recent call last): 2 File "C:/Call.py", line 4, in <module> 3 Main(array.array("q", range(100))) 4 File "Main.py", line 13, in Main.Main.__init__ 5 subA = SubA(subB) 6 File "SubA.py", line 9, in SubA.SubA.__init__ 7 self.subB = subB 8AttributeError: 'SubA.SubA' object has no attribute 'subB'

SubA側の@cython.cclassを取り除く事により、エラーなく動作しますが、高速化は4倍程度となります。
50~90倍程度の高速化を目標にしています。

以上、よろしくおねがいします

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問