0

这是代码:

class Animal:
    def __init__(self, animal_type):
        self.animal_type = animal_type

class Cat(Animal):
    def __init__(self, animal_type, favorite_food):
        super().__init__(animal_type)
        self.favorite_food = favorite_food

    def cat_print(self):
        print("{}'s favorite food is {}.".format(self.animal_type, self.favorite_food))

    def __getattribute__(self, item):
        print('__getattribute__() be called. Item is: ', item)

    def __getattr__(self, item):
        print('__getattr__() be called. Item is: ', item)

    def __setattr__(self, key, value):
        print('__setattr__() be called. key and Value is: ', key, value)


cat = Cat('cat', 'fish')
print(cat.animal_type)
print(cat.favorite_food)

当我打印时cat.animal_type,它打印无。我猜是因为我重写了 method: __setattr__()and __getattribute__(),所以值不能传递给属性。

我想知道在python中分配属性并获取类中的属性的过程是什么?

谢谢。

4

2 回答 2

1

您的所有属性都是 的原因None,即使是不存在的属性,例如favorite,是这样的:

def __getattribute__(self, item):
    print('__getattribute__() be called. Item is: ', item)

您正在object.__getattribute__使用始终返回的方法覆盖普通代码None。如果你想让它打印一些东西并做正常的事情,你必须明确地使用super——就像你在初始化器中所做的那样:

def __getattribute__(self, item):
    print('__getattribute__() be called. Item is: ', item)
    return super().__getattribute__(item)

如果你解决了这个问题,现在可以查找存在的属性,但不存在的属性仍然会返回None而不是引发AttributeError. 为什么?

def __getattr__(self, item):
    print('__getattr__() be called. Item is: ', item)

正常object.__getattribute__(您现在正确调用)在对象的__dict__、其类和所有其类的祖先中查找属性(与我将在此处忽略的描述符相关的一些额外复杂性),并且然后,如果什么都没有找到(或者找到了一些东西但获取它会引发AttributeError),它会调用类的__getattr__. 而你提供一个__getattr__返回None

在这里,您再次想委托给超类:

def __getattr__(self, item):
    print('__getattr__() be called. Item is: ', item)
    return super().__getattr__(item)

除了没有. _ __getattr__所以,你会得到一个AttributeError,但这将是关于一个super没有 a __getattr__,而不是关于一个Cat没有 a favorite

如果你知道你的一个基类想要__getattr__为你提供一个委托super给它。但是,如果您知道没有人这样做:

def __getattr__(self, item):
    print('__getattr__() be called. Item is: ', item)
    raise AttributeError(item)

如果你不知道(因为,比如说,你的类被设计成与其他人的类层次结构混合使用),你可能想要这样的东西:

def __getattr__(self, item):
    print('__getattr__() be called. Item is: ', item)
    try:
        ga = super().__getattr__
    except AttributeError:
        pass
    else:
        return ga(item)
    raise AttributeError(item)

如果你修复了这两个,现在你会得到AttributeError你设置的属性。为什么?

def __setattr__(self, key, value):
    print('__setattr__() be called. key and Value is: ', key, value)

同样的问题。在这里,您可能希望显式设置属性,如下所示:

def __setattr__(self, key, value):
    print('__setattr__() be called. key and Value is: ', key, value)
    super().__getattribute__('__dict__')[key] = value

……或者您可能只想再次委托:

def __setattr__(self, key, value):
    print('__setattr__() be called. key and Value is: ', key, value)
    super().__setattr__(key, value)
于 2018-08-08T06:53:00.287 回答
-3

在 Cat 类的init中添加:

self.animal_type = animal_type

并修改您的打印

print(cat.favorite)

print(cat.favorite_food)

然后分析并尝试理解你的错误:)

于 2018-08-08T06:44:37.493 回答