2016-12-31 3 views
1

だから私は事が正常に動作print(spot.get_name())あるオブジェクトはスーパークラスの関数ではありませんか?

error: " AttributeError: 'Dog' object has no attribute '_Dog__name'"

を得続けます。また、spot.multiple_sounds()も同様に失敗しました。私は問題がオブジェクト定義の関数でスーパークラスからオブジェクト属性を呼び出そうとしていると思います。なぜ私は理解できません。私はチュートリアルからこのすべてをやっていて、コードは彼と同じです。彼はpython2.xを使っているし、spyder python3.xを使っているかもしれないと思っていますが、私は分かりません。どんな助けでも大歓迎です。 Pythonで

import random 
import os 
import sys 

class Animal: 
    __name = "" 
    __height = 0 
    __weight = 0 
    __sound = 0 

    def __init__(self,name,height,weight,sound): 
     self.__name = name 
     self.__height = height 
     self.__weight = weight 
     self.__sound = sound 

    def set_name(self, name): 
     self.__name = name 

    def get_name(self): 
     return(self.__name) 

    def set_height(self, height): 
     self.__height = height 

    def get_height(self): 
     return(self.__height) 

    def set_weight(self, weight): 
     self.__weight = weight 

    def get_weight(self): 
     return(self.__weight) 

    def set_sound(self, sound): 
     self.__sound = sound 

    def get_sound(self): 
     return(self.__sound) 

    def get_type(self): 
     print("animal") 

    def toString(self): 
     return("{} is {} cm tall and {} kilograms and says {}".format(self.__name, 
                     self.__height, 
                     self.__weight, 
                     self.__sound)) 


cat = Animal('Whiskers', 33, 10,'Meow') 

print(cat.toString()) 

class Dog(Animal): 

    __owner = "" 

    def __init__(self, name, height, weight, sound, owner): 
     self.__owner = owner 
     super().__init__(name, height, weight, sound) 

    def set_owner(self,owner): 
     self.__owner = owner 

    def get_owner(self): 
     return self.__owner 

    def get_type(self): 
     print("Dog") 

    def toString(self): 
     return "{} is {} cm tall and {} kilograms says {} and his owner is {}".format(self.__name, self.__height, self.__weight, self.__sound, self.__owner) 

    def multiple_sounds(self, how_many=None): 
     if how_many is None: 
      print(self.getsound()) 
     else: 
      print(self.getsound()*how_many) 

spot = Dog("Spot", 53, 27, "Ruff", "Some Guy") 
print(spot.get_name()) 
print(spot.toString()) 
+0

小規模な例が優れているされて...あなたが読みやすいサンプルプログラムにそのほとんどをトリムでしたが、問題を示しています。 – tdelaney

+1

@ e4c5 - 私はそれがdupのために十分に近いとは思わない。これは、主に '__init__'のような特別なメソッドについて話しています。 – tdelaney

+0

ok @tdelaney retracting – e4c5

答えて

2

__fieldNameは、プライベートフィールドをエミュレートし、フィールド名であること2つのアンダースコアを意味します。そのようなフィールドは派生クラスからは到達できませんが、getterを使用して取得することはできます。

+0

すべての変数からダブルアンダースコアを削除してもうまく機能しましたが、ゲッターを使ってどのように呼び出すのですか? – whydoesmycodehateme

+0

self.get_name()、子クラスにプライベート変数が必要な場合は、getterはpublicです。 –

0

二重下線で始まり、0または1のアンダースコアで終わる名前は、private変数に対するpythonの答えです。 Pythonはそれらを__Class_nameにして、継承されたサブクラスではなくクラスにプライベートにします。そのアイデアは、クラス内の名前を持つことができるようにすることです。明らかに、これはよく知られているmunged名を使って簡単に破壊されますが、Pythonは動的言語です。

Private Variables

1

を参照してください「__」で始まる任意の属性やメソッドは、同じクラス内の関数からその名前のだけアクセス可能です。他のクラスからではなく、サブクラスからのものでもありません。上記のコードで

class A: 
    def __init__(self, name): 
     self.__name = name 

    def get_name(self): 
     return self.__name 

class B(A): 
    def get_name_capitalized(self): 
     return self.__name.upper() 

b = B('Bob') 
print(b.get_name()) # prints 'Bob' 
print(b.get_name_capitalized()) # fails 

A.get_name()を呼び出すことに成功し、インスタンスの__name属性にアクセスします。しかしB.get_name_capitalized()は "AttributeError: 'B'オブジェクトの属性に '_B__name' "という属性がありません。 "__"の名前は、そのままコンパイルできないように、コンパイラーによってmangledされます。 get_name_capitalized内のコードに変更されている場合:

return self._A__name.upper() 

それが動作しますので、これらの属性アクセス可能ですが、あなたはそれらを得るために変換された名前を使用する必要があります。

Pythonは1.1以降となっている方法です、とPython 3で新しい何も

関連する問題