对象不是来自超类的函数吗?

时间:2016-12-31 06:10:29

标签: python class object spyder

所以我一直得到

  

错误:“AttributeError:'Dog'对象没有属性'_Dog__name'”

事情是print(spot.get_name())正常。此外,当我尝试spot.multiple_sounds()同样失败时。我认为问题是当我尝试从对象定义中的函数中的超类调用对象属性时。我无法理解为什么。我正在从教程中完成所有这些,代码与他的相同。我想这可能是因为他正在使用python2.x而我正在使用spyder python3.x但我不知道。非常感谢任何帮助。

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())

3 个答案:

答案 0 :(得分:2)

在python中,__fieldName模拟私有字段,表示字段名称中的两个下划线。因此,无法从派生类中访问这些字段,但您仍然可以使用getter获取它们。

答案 1 :(得分: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()成功访问A实例的__name属性。但是B.get_name_capitalized()失败并出现错误"属性错误:' B'对象没有属性' _B__name' &#34 ;. " __"名称被编译器破坏,因此它们不能按原样访问。如果get_name_capitalized中的代码更改为:

    return self._A__name.upper()

然后它会工作,所以这些属性 可以访问,但你必须使用受损的名称来获取它们。

这就是Python从1.x开始的过程,对于Python 3来说并不是什么新鲜事。

答案 2 :(得分:0)

以双下划线开头并以零或1下划线结尾的名称是python对私有变量的回答。 Python将它们称为__Class_name,使它们对类是私有的,而不是它的继承子类。这个想法是让你有没有子类的类内名称搞乱他们。显然,使用众所周知的munged名称很容易破坏它,但是,python是一种动态语言。

请参阅Private Variables