1

渡した文字列に基づいて、クラス内の関数を呼び出そうとしています。

このリンクの手順に従ってみました: Pythonで関数の名前を持つ文字列からモジュールの関数を呼び出す

これが私のコードです:

methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)

listOfPlayerFleets[currentPlayer].methodToCall(num)

エラーが発生します:

AttributeError:fleet instance has no attribute 'methodToCall'

methodToCallに正しいメソッド名が割り当てられない理由について何か考えはありますか?

私も試しました

methodToCall = getattr(fleet, methodToCall)

次に、次のメッセージが表示されます。

AttributeError: 'module' object has no attribute 'addCruiser'

getattrが私のクラスで私のメソッドを見つけることができないかのようです。

listOfPlayerFleetsは、フリートオブジェクトのリストです

これは、メソッドが実際に存在することを確認できるフリートオブジェクトの外観です。

class fleet:
    """ Stores Fleet Numbers, Represents a fleet """

    ships = {'fighters':0, 'cruisers':0, 'capitols':0}
    attacking = False
    defending = False

    def __init__(self):
        self.ships = {'fighters':0, 'cruisers':0, 'capitols':0}
        self.attacking = False
        self.defending = False

    #add a Fighter
    def addFighter(self, numOfFighters):
        self.ships['fighters'] = numOfFighters


    #add a Cruiser
    def addCruiser(self, numOfCruisers):
        self.ships['cruisers'] = numOfCruisers

    #add a Capitol Ship
    def addCapitol(self, numOfCapitols):
        self.ships['capitols'] = numOfCapitols
4

4 に答える 4

3

methodToCall変数はバインドされたメソッドです。つまり、オブジェクトで呼び出す必要はありません。変数は、呼び出されるオブジェクトを認識しています 。fleet.addFighterたとえば、はバインドされていないメソッドです。印刷repr(methodToCall)し、repr(fleet.addFighter)これを明確にする必要があります。

これを使用する必要があります:

methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)

methodToCall(num)
于 2011-02-04T14:29:26.800 に答える
2

それはそれをする必要があります。

methodNameString = "add" + typeOfShip
methodToCall = getattr(listOfPlayerFleets[currentPlayer], methodNameString)

methodToCall(num)

getattr、その特定のインスタンス(listOfPlayerFleets[currentPlayer])のメソッドへの参照を提供するため、パラメーターを使用して呼び出すだけです。

于 2011-02-04T14:29:20.197 に答える
1

まず、この種のことは、辞書を使用するなどの適切な解決策と同等になることはめったになく、それらよりも優れていることはめったにありません。あなたは適切にそうする方法addShip(kind, num)を持っているはずself.ships[kind] += numです。はるかにクリーンで、拡張が簡単で、DRY(繰り返してはいけません)、そして追加のボーナスとしてもより速くなります。

エラーについて:listOfPlayerFleets[currentPlayer].methodToCall(num)呼び出されたメソッドを呼び出そうとしますmethodToCall(これは明らかに存在しません。getattr(listOfPlayerFleets[currentPlayer], methodNameString)すでに必要なメソッドを取得しており、バインドされたメソッドです。つまり、呼び出すmethodToCall()と、権利selfが渡されます。

もう1つのエラー('method' object has no ...)は、モジュールとそれに含まれるもの(クラスなど)の間に違いがあるためです。は?class fleetというモジュールにあると思います。fleet次に、が必要fleet.fleetです。ちなみに、クラスにはCamelCaseで名前を付ける必要があります。スタイルガイドのPEP8を参照してください

于 2011-02-04T14:31:43.673 に答える
0

試しましたか

func = getattr(obj, "method")
if callable(func):
  result = func(args)
于 2011-02-04T14:37:38.040 に答える