为什么一个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
,而不是一个没有 favorite
的 Cat
.
如果您知道您的一个基地 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)
代码如下:
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
,而不是一个没有 favorite
的 Cat
.
如果您知道您的一个基地 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)