为什么一个class的属性被设置了一个值,却打印了一个None类型?

Why an attribute of a class be set a value, but print a None type?

代码如下:

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 时,它会打印 None。我猜是因为我重写了方法:__setattr__()__getattribute__(),值无法传递到属性中。

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

谢谢。

init 中添加这个 class Cat:

self.animal_type = animal_type

并修改您的印刷品

print(cat.favorite)

print(cat.favorite_food)

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

你的所有属性都是 None,甚至像 favorite 这样不存在的属性的原因是:

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

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

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

如果您修复该问题,现在可以查找存在的属性,但不存在的属性仍然会 return None 而不是引发 AttributeError。为什么?

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

正常 object.__getattribute__(您现在正确调用)在对象的 __dict__ 及其 class 及其所有 class 中查找属性] 的祖先(与我将在这里忽略的描述符相关的一些额外的复杂性),然后,如果没有找到任何东西(或者找到了一些东西但获取它会引发 AttributeError),它调用class 的 __getattr__。你提供了一个 __getattr__ 那个 returns None.

在这里,你又想委托给超级classes:

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

除了 没有 __getattr__ 的默认实现。所以,你会得到一个 AttributeError,但它是关于一个没有 __getattr__super,而不是一个没有 favoriteCat .

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

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

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

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)