因为 Person 类没有自己写这套规则,所以它继承了老祖宗 object 提供的默认规则
class Person:
skin = "yellow"
def init(self,name,age):
self.name = name
self.age = age
那skin属性是通过对象访问object的__getattribute__的skin吗
skin 是“数据存储”(属性/数据):它是实实在在的数据。它被定义在 Person 类中,所以它存放在 Person 类的字典(Person.__dict__)里。在这里,“引擎”是一个比喻。它具体指的是 __getattribute__ 这个魔术方法本身,以及它背后 Python 解释器(通常是 CPython)的底层 C 语言代码。
Python 代码层面:引擎 = __getattribute__ 方法
在 Python 语言的规则里,这个“引擎”就是 __getattribute__ 方法。
__dict__,再查类的 __dict__,再查父类的 __dict__,最后找不到就报错。p.skin 时,就是启动了这台名为 __getattribute__ 的机器,让它按照既定程序去帮你找数据为什么我要用“引擎”这个词来比喻?
因为 点号 .(属性访问运算符) 本身只是一个“语法符号”,它就像汽车的“油门踏板”。 而 __getattribute__(及其底层的 C 函数) 才是真正提供动力、执行复杂查找逻辑的“发动机(引擎)”。
当你踩下油门(输入 p.skin),引擎(__getattribute__)就开始轰鸣运转,按照特定的机械顺序(查实例 -> 查类 -> 查父类)去完成任务。
当你执行 p.skin 时,Python 底层真实发生的事情如下:
p 的 skin,于是调用 object.__getattribute__(p, 'skin')。(因为 Person 没重写,所以用 object 的)。p 自己的口袋(p.__dict__)里找 skin。发现只有 name 和 age,没找到 skin。p 所属的类(Person.__dict__)里找。在 Person 的字典里发现了 'skin': 'yellow',于是把 'yellow' 返回给你。(注:如果 Person 类里也没有 skin,引擎才会继续往上去 object.__dict__ 里找,但 object 里显然没有 skin,最后就会报错 AttributeError。)