Python类变量赋值机制:实例赋值与类赋值的差异解析

Owen
Owen
发布时间:2026-10-13 | 2人浏览过
原创

本文深入解析Python中类变量的两种赋值方式及其对对象状态的影响。通过对比实例直接赋值与通过类名修改类变量,阐明Python属性查找机制(从实例__dict__到类__dict__)的工作原理。文章还补充了关于__dict__、__class__及__bases__的核心概念,以及类方法调用的底层逻辑,帮助开发者避免常见的变量作用域混淆问题。

类变量赋值的两种行为对比

为了直观展示差异,我们直接通过代码示例进行分析。


# -*- coding:utf-8 -*-
#面试题,写一个方法,将一行字符串中所有的单词数量统计出来
 
class Person(object):
 TAG = "hello"
 
p1 = Person()
p2 = Person()
 
print p1.TAG #第一种赋值方式
print p2.TAG
print Person.TAG #第二种赋值方式
 
p1.TAG = "damn it"
 
print p1.TAG
print p2.TAG
print Person.TAG

运行上述代码后,输出结果显示:仅实例p1的TAG属性被修改为新的值"damn it",而p2和类本身的TAG仍保持原值。


hello
hello
hello
damn it
hello
hello

若希望所有通过该类创建的对象共享同一更新后的类变量值,应如何处理?

Person.TAG = "damn it"

再次运行程序,输出结果如预期所示:所有实例及类本身均读取到了最新的TAG值,问题得到解决。


hello
hello
hello
damn it
damn it
damn it

Python类、赋值与命名空间机制

补充知识:Python类、赋值操作与命名空间机制

在Python中,类本质上是一个命名空间。访问object.attr的过程,实际上是沿着属性查找链向上搜索的过程。

核心属性包括:__dict__、__class__和__bases__。

其中,__dict__存储实例、类或模块的属性字典;__class__指向实例所属的类对象;__bases__是一个元组,包含父类或超类列表。

属性与类的查找过程

属性查找(Attribute Lookup)过程如下:


def findAttr(obj , attr):
 if attr in obj.__dict__:
  return obj.__dict__[attr]
 cls = obj.__class__
 if attr in cls.__dict__:
  return cls.__dict__[attr]
 for super_cls in cls.__bases__:
  if attr in super_cls.__dict__:
   return super_cls.__dict__[attr]
 return None

类继承树查找过程:


def classTree(cls,indent):
 print('.'*indent + cls.__name__)
 for super_cls in cls.__bases__:
  classTree(super_cls,indent+4)

类方法调用的实现原理

赋值操作的两种主要方式:


class Test:
 static_var = 1 #类属性相当与C++静态成员变量
 def assign(self):
  self.x = 1 #对象属性赋值
 
t = Test()
t.x = 2 #也可以这样 ,直接赋值
t.__dict__['x'] = 3 #也可以这样 , __dict__是对象空间词典,每个对象一份,类对象/模块也有
Test.add_static_var = 5 #也可以样新增一个类属性

类方法调用通常采用object.method()形式,在Python内部等价于扩展写法Class.method(object),两者效果一致。

Test.assign(t) print(t.x)

当使用object.method()时,object自动作为第一个参数传入method(self)中;而使用Class.method(object)时,则需要手动传入该对象。

命名空间与变量作用域详解

关于命名空间的具体行为:


x = 0
def print_global():
 print(x) #打印全局
def print_local():
 x = 1
 print(x) #本地变量
class A:
 x = 2 #类属性==C++静态成员变量 , print A.x
 def m(self):
  x = 3   #本地变量
  self.x = 4 #对象属性

def change_global():
 global x  #修改全局变量,否则x = 100 ,是增加一个本地变量
 x = 100
def print_enclosing():
 x = 200
 def nested():
  print(x)  #在闭包中引用本地变量
def change_in_enclosing():
 x = 1
 def nested():
  nonlocal x
  x = 2   #在闭包中改变本地变量, 如没有nonlocal x , 在又新增一个本地变量

以上即为Python中类变量两种赋值方式的区别详解,希望能为读者提供清晰的理解与参考,欢迎继续支持本站获取更多技术内容。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表