类变量和全局变量的查找路径有什么区别?

Python:类变量 vs 全局变量 ------ 查找路径区别

Python 名字查找遵循两套独立规则:作用域链(用于普通变量名) 、属性查找链(用于对象。属性)

一、全局变量的查找路径(名字查找:单纯变量名,不带 .)

复制代码
g = 100
def foo():
    print(g)

查找顺序(LEGB 规则):

  1. L Local :当前函数局部命名空间 → 找 g
  2. E Enclosing :外层嵌套函数闭包命名空间 → 找 g
  3. G Global :当前模块命名空间(模块__dict__) → 找到全局变量 g
  4. B Builtin :内置命名空间(builtins)

关键点:

  • 全局变量属于名字空间查找,是 LEGB;
  • 只在写操作的时候需要 global 声明,告诉解释器不要新建局部变量,去 G 层修改。

二、类变量的查找路径(属性查找,一定带 .)

类变量存在类对象的__dict__,访问分两种写法:

写法 1:类名.属性 例如 A.x

  1. 取类对象 A
  2. 在 A.__dict__ 直接查找 x
  3. 找不到就沿着继承链(MRO) 向上找父类的__dict__

不会走到模块全局命名空间!

写法 2:实例.属性 例如 a.x(最常用,坑最多)

复制代码
class A:
    x = 200
a = A()
print(a.x)

属性查找顺序(obj.__getattr__ 默认逻辑):

  1. 实例 a.__dict__ :先看实例自己有没有 x
  2. 如果实例没有,再去**类 A.__dict__**查找类变量
  3. 还找不到,沿着 MRO 向上遍历所有父类
  4. 全部找不到抛出 AttributeError

⚠️ 重点:a.x = 999 是往实例__dict__写入 ,不会修改类变量 。之后读取a.x直接读到实例字典的值,不再访问类变量。


三、核心对比:两条完全不同的查找体系

  • 全局变量:LEGB 名字查找,是解析器对裸变量名(不带点)的解析规则。
  • 类变量:属性查找(.操作符) ,是对象属性的查找规则,不走 LEGB。

举个例子区分两者:

复制代码
x = 10  # 全局变量
class A:
    x = 20  # 类变量

a = A()
print(x)        # 裸名,LEGB → 全局x=10
print(A.x)      # .属性查找 → 类A的x=20
print(a.x)      # .属性查找 → 实例无x,找到类A.x=20

四、查找路径对比表

表格

项目 全局变量(裸变量名) 类变量(obj.x/ Class.x)
查找体系 LEGB 名字作用域链 对象属性查找链 + MRO 继承链
查找顺序 局部 → 闭包 → 模块全局 → builtin 实例 dict → 当前类 dict → MRO 父类链
存储位置 模块__dict__ 类__dict__
是否经过继承链 ❌ 不涉及继承 ✅ 会沿着 MRO 父类向上查找
查找触发 直接写变量名(不带.) 使用 . 属性访问运算符
会不会跑到 builtin ✅ LEGB 最后一层是 builtin ❌ 属性查找默认不走 builtin 命名空间

五、容易混淆的场景

复制代码
x = 1
class A:
    x = 2
    def func(self):
        print(x)      # 裸名!LEGB,取全局x=1
        print(self.x) # .属性查找,类变量x=2

这里print(x)和print(self.x)完全不是一条查找路线,很多人踩坑!

六、性能层面补充

  1. 裸名全局变量:需要走完 LEGB,相对慢
  2. 类名.属性:直接查类 dict,查找路径短,更快mp.qingtianyu.cn/blog/9kLm2QpX7a.html
    mp.qingtianyu.cn/blog/Zx4Tn8Vr1B.html
    mp.qingtianyu.cn/blog/Qw7Yh3Ns5D.html
    mp.qingtianyu.cn/blog/Mc2Jv9Kp6E.html
    mp.qingtianyu.cn/blog/Rt8Bn4Xz0F.html
    mp.qingtianyu.cn/blog/Hg5Lp1Wq7G.html
    mp.qingtianyu.cn/blog/Uv3Dm6Yr2H.html
    mp.qingtianyu.cn/blog/Pa9Kc4Nt8J.html
    mp.qingtianyu.cn/blog/Se2Qx7Vb5K.html
    mp.qingtianyu.cn/blog/Fn6Wm1Zp3L.html
    mp.qingtianyu.cn/blog/Yd4Hr9Cv2M.html
    mp.qingtianyu.cn/blog/Jk7Tq3Bs8N.html
    mp.qingtianyu.cn/blog/Ol1Pm5Xw6P.html
    mp.qingtianyu.cn/blog/Bg8Nc2Vr4Q.html
    mp.qingtianyu.cn/blog/Xm5Kt7Yd1R.html
    mp.qingtianyu.cn/blog/Cv9Qp3Ln6S.html
    mp.qingtianyu.cn/blog/Zr2Wm8Hx4T.html
    mp.qingtianyu.cn/blog/Nk6Jd1Vp9U.html
    mp.qingtianyu.cn/blog/Lq4Yt7Bc2V.html
    mp.qingtianyu.cn/blog/Wp8Rm3Nx5W.html
    mp.qingtianyu.cn/blog/Td1Kv6Qs9X.html
    mp.qingtianyu.cn/blog/Hx5Pm2Zr7Y.html
    mp.qingtianyu.cn/blog/Gc9Bn4Wt1Z.html
    mp.qingtianyu.cn/blog/Vr3Lq8Jd6A.html
    mp.qingtianyu.cn/blog/Mp7Yx2Kc5B.html
    mp.qingtianyu.cn/blog/Ks4Wm9Nv3C.html
    mp.qingtianyu.cn/blog/Qn1Rt6Bp8D.html
    mp.qingtianyu.cn/blog/Dz5Jv2Xm7E.html
    mp.qingtianyu.cn/blog/Sb9Lq4Hr1F.html
    mp.qingtianyu.cn/blog/Yt3Pm8Kx6G.html
    mp.qingtianyu.cn/blog/Rc7Wn1Vd4H.html
    mp.qingtianyu.cn/blog/Bp2Qx9Lm5J.html
    mp.qingtianyu.cn/blog/Nv6Tr3Yc8K.html
    mp.qingtianyu.cn/blog/Lm1Jd7Wp2L.html
    mp.qingtianyu.cn/blog/Xq5Kv9Bn4M.html
    mp.qingtianyu.cn/blog/Ct8Rm2Hx7N.html
    mp.qingtianyu.cn/blog/Zp3Yq6Ld1P.html
    mp.qingtianyu.cn/blog/Gv9Wm4Nc5Q.html
    mp.qingtianyu.cn/blog/Hk2Jx7Rt8R.html
    mp.qingtianyu.cn/blog/Md6Pq1Bv3S.html
    mp.qingtianyu.cn/blog/Tn8Lm5Wx2T.html
    mp.qingtianyu.cn/blog/Qr4Yp9Kc7U.html
    mp.qingtianyu.cn/blog/Vx1Jv6Nd3V.html
    mp.qingtianyu.cn/blog/Kp7Wm2Ht9W.html
    mp.qingtianyu.cn/blog/Bc5Rq8Lx4X.html
    mp.qingtianyu.cn/blog/Nm9Yd3Pv1Y.html
    mp.qingtianyu.cn/blog/Lt2Kx7Bc6Z.html
    mp.qingtianyu.cn/blog/Xv8Qm4Nr5A.html
    mp.qingtianyu.cn/blog/Cp1Jd9Wt3B.html
    mp.qingtianyu.cn/blog/Zk6Lq2Yx8C.html
    mp.qingtianyu.cn/blog/Gr3Pm7Vc1D.html
    mp.qingtianyu.cn/blog/Hx9Bn5Kd4E.html
    mp.qingtianyu.cn/blog/Mv2Tq8Lm6F.html
    mp.qingtianyu.cn/blog/Tc7Yp1Rx3G.html
    mp.qingtianyu.cn/blog/Qm4Jv9Wd5H.html
    mp.qingtianyu.cn/blog/Vp8Km2Nx7J.html
    mp.qingtianyu.cn/blog/Kd1Lq6Bt9K.html
    mp.qingtianyu.cn/blog/Bx5Rm3Yc2L.html
    mp.qingtianyu.cn/blog/Nq9Pv7Hd4M.html
    mp.qingtianyu.cn/blog/Lm3Jx1Wt6N.html
    mp.qingtianyu.cn/blog/Xc8Qm5Bv2P.html
    mp.qingtianyu.cn/blog/Cv4Kd9Nr7Q.html
    mp.qingtianyu.cn/blog/Zp1Yq6Lx3R.html
    mp.qingtianyu.cn/blog/Gt7Wm2Vc9S.html
    mp.qingtianyu.cn/blog/Hk5Jv8Rd1T.html
    mp.qingtianyu.cn/blog/Mx9Pq3Bn6U.html
    mp.qingtianyu.cn/blog/Tm2Ld7Wv4V.html
    mp.qingtianyu.cn/blog/Qc6Yp1Kx8W.html
    mp.qingtianyu.cn/blog/Vr3Jm9Nt5X.html
    mp.qingtianyu.cn/blog/Kp8Qv4Bd2Y.html
    mp.qingtianyu.cn/blog/Bm1Lx6Wc7Z.html
    mp.qingtianyu.cn/blog/Nv5Rd9Yp3A.html
    mp.qingtianyu.cn/blog/Lq2Km7Jx8B.html
    mp.qingtianyu.cn/blog/Xt9Pm4Vc1C.html
    mp.qingtianyu.cn/blog/Cd3Qv8Bn6D.html
    mp.qingtianyu.cn/blog/Zx7Lp2Yr5E.html
    mp.qingtianyu.cn/blog/Gm1Jd6Wv9F.html
    mp.qingtianyu.cn/blog/Hv4Kq9Nx2G.html
    mp.qingtianyu.cn/blog/Mp8Rm3Bc7H.html
    mp.qingtianyu.cn/blog/Tq1Yv5Ld4J.html
    mp.qingtianyu.cn/blog/Qx6Jm2Wt9K.html
    mp.qingtianyu.cn/blog/Vc3Pq7Rn1L.html
    mp.qingtianyu.cn/blog/Km9Ld4Bv6M.html
    mp.qingtianyu.cn/blog/Bp2Xv8Yc3N.html
    mp.qingtianyu.cn/blog/Nr5Qm1Jx7P.html
    mp.qingtianyu.cn/blog/Lv8Kd3Wt2Q.html
    mp.qingtianyu.cn/blog/Xm4Pq9Bc6R.html
    mp.qingtianyu.cn/blog/Ct1Rv7Lx5S.html
    mp.qingtianyu.cn/blog/Zp8Jm2Yd4T.html
    mp.qingtianyu.cn/blog/Gq3Kv6Nx9U.html
    mp.qingtianyu.cn/blog/Hm7Ld1Wc5V.html
    mp.qingtianyu.cn/blog/Mv4Pq8Bt2W.html
    mp.qingtianyu.cn/blog/Tr9Ym3Jx6X.html
    mp.qingtianyu.cn/blog/Qc2Kv7Ld1Y.html
    mp.qingtianyu.cn/blog/Vp6Rm4Nc8Z.html
    mp.qingtianyu.cn/blog/Kx1Jd9Wv3A.html
    mp.qingtianyu.cn/blog/Bm5Qq2Yt7B.html
    mp.qingtianyu.cn/blog/Nc8Lm4Hx1C.html
    mp.qingtianyu.cn/blog/Lv3Pq9Rd6D.html
    mp.qingtianyu.cn/blog/Xt7Km2Bc5E.html
  3. 实例.属性:优先查实例 dict;实例没有才上类,多一次字典查询

性能差距很小;热点循环统一缓存到局部变量是最优方案。

如果你想,我可以用dis字节码,打印两种查找对应的底层字节指令,直观看到查找过程。

相关推荐
卷无止境2 小时前
独立开发者的"富矿地带":哪些垂直领域值得你押注一辈子?
后端·python
\光辉岁月/2 小时前
5.java-数组
java·开发语言
Java后端的Ai之路2 小时前
Python进阶探索29_eval内置函数
开发语言·python·探索·eval·内置函数
计算机毕业编程指导师2 小时前
计算机毕设选题推荐:基于Hadoop与Spark的Steam游戏数据分析系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·spark·毕业设计·steam游戏
计算机毕业编程指导师2 小时前
【计算机毕设选题推荐】基于Hadoop+Spark的白鹿抖音评论大数据分析与可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习 深度学习
大数据·hadoop·python·计算机·spark·毕业设计·抖音评论
谢亮_vipxieliang2 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot
Zootopia6262 小时前
飞行力学知识梳理1|飞行性能与稳定性
人工智能·python·算法·机器学习·无人机·学习方法·信息与通信
Y3815326622 小时前
搜索 API 延迟优化:并发数、超时与超时的真实代价
python·搜索引擎
时间的拾荒人2 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试