1

バインドされたメソッド、継承、およびgetattrの間の相互作用で、私が理解できていない奇妙なことが起こっています。

私は次のようなディレクトリ設定をしています:

/a
__init__.py
start_module.py
  /b
  __init__.py
  imported_module.py 

import_module.pyには、次の形式のクラスオブジェクトがいくつか含まれています。

class Foo(some_parent_class):
    def bar(self):
       return [1,2,3]

start_module.pyの関数は、inspectを使用して、imported_module.pyのクラスを表す文字列のリストを取得します。「Foo」はそれらの文字列の最初のものです。目標は、その文字列とgetattrを使用してstart_module.pyでbarを実行することです。*

これを行うには、次の形式のstart_moduleのコードを使用します。

for class_name in class_name_list:
  instance = getattr(b.imported_module, class_name)()
  function = getattr(instance, "bar")
  for doodad in [x for x in function()]:
     print doodad 

これはリスト内包表記の反復を正常に開始しますが、最初の文字列「bar」で奇妙なエラーが発生します。バーはバインドされたメソッドですが、Fooのインスタンスを引数として期待していることを理解している限り、次のように言われます。

TypeError:bar()は引数を取りません(1つ指定)

これにより、function()の呼び出しがFooインスタンスを渡しているように見えますが、コードはそれを受け取ることを期待していません。

私はここで何が起こっているのか本当にわかりませんし、GoogleとStackOverflowを見て説明を解析することもできませんでした。ダブルgetattrは奇妙な相互作用を引き起こしていますか?Pythonのクラスオブジェクトについての私の理解はあまりにも曖昧ですか?私はあなたの考えを聞いてみたいです。

*アンチパターンを回避するための実際の最終目的は、start_module.pyがimported_module.pyのFooと同様のさまざまなクラスの名前バーのすべてのメソッドに自動的にアクセスできるようにすることです。私は、後継者がFooに似たクラスの数が非常に多い可能性があるもののリストを維持することを回避することを期待してこれを行っています。

以下の回答:ここでの最大のポイントは、検査が非常に役立つことです。発生しているバグの一般的な原因がある場合は、他の可能性を探す前に、それを除外したことを絶対に確認してください。この場合、ファイル構造が最近編集されたために、正しいコードを持っているモジュールがインポートされていない可能性があるという事実を見落としていました。

4

3 に答える 3

3

あなたが投稿したサンプルコードが間違っているので、どこかにFooクラスを持つ別のモジュールがあると思います-多分barこのように定義されています

class Foo(object):
    def bar():   # <-- missing self parameter
        return [1,2,3]

これはそのエラーメッセージを出します

>>> Foo().bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar() takes no arguments (1 given)
于 2013-01-10T01:34:49.107 に答える
2

クラスメソッドには、self基本的に自動的に渡される引数があります。これは、メソッドを呼び出しているクラスインスタンスにすぎません。別のパラメーターを渡す必要はありません。

于 2013-01-10T01:28:28.440 に答える
2

発生したエラーを再現できません。これが、Pythonシェルから実行される、自己完結型の短いコンパイル可能な例での私の試みです。

>>> class Foo(object):
    def bar(self):
        print("Foo.bar!")

>>> import __main__ as mod
>>> cls = getattr(mod, "Foo")
>>> inst = cls()
>>> func = getattr(inst, "bar")
>>> func()
Foo.bar!

おそらく、inspectベースのコードをこのような例に適合させて、どこで問題が発生しているかを確認することができます。

于 2013-01-10T03:29:33.813 に答える