web-dev-qa-db-ja.com

Python-オブジェクトに属性エラーがありません

クラス全体を別のファイルに最初から書き直し、すべてが魔法のように機能し、条件文などすべてが機能しました。そのため、そのクラスといくつかの関数を新しいファイルからマスターファイルにインポートしました。まだありません。何が最初にうまくいかなかったのか考えてください。

以下の問題は技術的に解決されたことに注意してください。コードの下部にタイプミスがあります。ただし、次の問題が明らかになりました。すべての条件(if、tryなど)が機能を停止したため、別のモジュールでクラスを書き直しました

Iwould誰もがどこにも行かなかったので、この投稿を削除しますが、どうやらStack Overflowではそうはいきません。

了解しました。私はPython 3.4を学び、練習として宿題をすることにしました。2人が戦うという非常に基本的なシミュレーションを行うスクリプトを作成し始めました。私が学んだ新しいこと(GUIの追加など)でそれを行います。

スクリプトは正常に開始されましたが、変更を加えるほど、エラーが表示され始めました。これで、次のようなエラーがスローされない限り、「ファイター」クラスのどのフィールドにもアクセスできなくなります。

'duelist' object has no attribute '_duelist__health'

'duelist'オブジェクトには属性 '_duelist__XXX'」以外に、タイプミス以外にエラーはありませんでした。グーグルは残念ながらこれを手伝うことができなかったので、それが私が私の最初のStackOverflow投稿をしている理由です。

これが最初のエラーハッピーフィールド「health」までのクラスです。

class duelist:
    def __init__(self):
        self.name = "Duelist" #must not be ""
        self.health = 5 #must be >0
        self.damage = [1, 3] #random attack range. Must be >=0 0 and the first must not be higher.
        self.skill = 10 #% chance to pass a skill check. Representative of parrying/dodging. Must be >=0
        self.shield = True #can block?
        self.shieldE = 80 #max block %. Must be >0
        self.agility = 0.5 #rate of attack in seconds. Must be >=0.05
        self.precision = 10 #critical hit chance. Must be >=0
        self.critical = 2.0 #critical multiplier. Must be >= 1.1


    #name
    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, value):
        if value != "":
            self.__name = value
        else:
            print("Invalid Name.\n")
    #name

    #health
    @property
    def health(self):
        return self.__health

    @health.setter
    def health(self, value):
        try:
            value = value(int)
            if value>=1:
                self.__health = value
            else:
                print("Health must be above 0.\n")
        except:
            print("Invalid Health.\n")
    #health

また、フィールド名を「__」を含まないように(または「__」をどこにでも含めるように)変更することを提案している場合は、無限ループが発生します。正確にこれを入力してください:

class duelist:
    def __init__(self):
        self.health = 5

    @property
    def health(self):
        return self.__health

    @health.setter
    def health(self, value):
        self.__health = value

D = duelist()
print(D.health)
D.health = 15
print(D.health)

正しく返されます

5
15
5

例外canは、クラスがその__init__()メソッドで属性__healthを定義していない場合に発生します。その値を読み取ろうとすると、問題が発生します。属性は、setterメソッドを(属性割り当てを介して間接的に)呼び出すことによって作成され、その後、属性が使用可能になります。

クラスの簡略版は次のとおりです。

class Duelist:
    def __init__(self):
#        self.health = 5
        pass

    @property
    def health(self):
        return self.__health

    @health.setter
    def health(self, value):
        self.__health = value

>>> d = Duelist()
>>> d.health
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "p.py", line 9, in health
    return self.__health
AttributeError: 'Duelist' object has no attribute '_Duelist__health'
>>> d.health = 123
>>> d.health
123

したがって、これを修正する1つの方法は、same nameを使用して属性を初期化することです。

class Duelist:
    def __init__(self):
#        self.health = 5    # this will also work
        self.__health = 5

>>> d.health
5
>>> d.health = 123
>>> d.health
123

したがって、プロパティ(self.health)または基になる属性(self.__health)を初期化しないと例外が発生することを考えると、問題の原因となる実際のコードを投稿しましたか?

1
mhawke