python类变量和实例变量
python类变量和实例变量
在类体中,根据变量定义的位置不同,以及定义的方式不同,类属性可细分为以下 3 种类型:
- 类体中,所有函数之外:此范围定义的变量,称为类属性或类变量
- 类体中,所有函数内部:以“self.变量名”的方式定义的变量,称为实例属性或实例变量
- 类体中,所有函数内部:以“变量名=变量值”的方式定义的变量,称为局部变量
类变量(类属性)
定义
类变量指的是在类中,但在各个类方法外定义的变量。举个例子:
class People:
# 定义两个类变量
name = "lilei"
age = 15
def __init__(self):
pass
上面的程序中,name
和age
就是类变量
调用
类变量的调用方式有 2 种:
- 使用类名直接调用
- 使用类的实例化对象调用(不推荐)
类名直接调用
# 使用类名直接调用
print(People.name)
print(People.age)
print("="*5, "修改类变量的值", "="*5)
# 修改类变量的值
People.name = "hanmeimei"
People.age = 18
print(People.name)
print(People.age)
lilei
15
===== 修改类变量的值 =====
hanmeimei
18
可以看到,通过类名不仅可以调用类变量,也可以修改它的值。
类的实例化对象调用(不推荐)
【注】此方式不推荐使用,原因后面解释
class People:
# 定义两个类变量
name = "lilei"
age = 15
a_man = People()
print(a_man.name)
print(a_man.age)
lilei
15
特性
- 所有类的实例化对象都同时共享类变量
- 类变量在所有实例化对象中是作为公用资源存在的。
- 类变量为所有实例化对象共有,通过类名修改类变量的值,会影响所有的实例化对象。
class People:
# 定义两个类变量
name = "lilei"
age = 15
print("修改前,实例1中类变量的值:")
man_a = People()
print(man_a.name)
print(man_a.age)
print("修改前,实例2中类变量的值:")
man_b = People()
print(man_b.name)
print(man_b.age)
People.name = "hanmeimei"
People.age = 233
print("修改类变量后,实例1中类变量的值:")
print(man_a.name)
print(man_a.age)
print("修改类变量后,实例2中类变量的值:")
print(man_b.name)
print(man_b.age)
修改前,实例1中类变量的值:
lilei
15
修改前,实例2中类变量的值:
lilei
15
修改类变量后,实例1中类变量的值:
hanmeimei
233
修改类变量后,实例2中类变量的值:
hanmeimei
233
由结果可以看出,通过类名修改类变量,会作用到所有的实例化对象(例如这里的 man_a 和 man_b)
通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量
实例变量(实例属性)
定义
实例变量指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象
class Person:
def __init__(self):
self.name = "zhangsan"
self.age = 18
def add_instance_val(self):
self.single = True
在Person
类中,name
,age
,single
都是实例变量,其中,
__init__
函数在创建类对象的时候会自动调用,从而将会自动定义name
,age
这两个实例变量- 而
single
这个实例变量只有在add_instance_val
这个函数执行的时候才会被定义
例1
class Person:
def __init__(self):
self.name = "zhangsan"
self.age = 18
def add_instance_val(self):
self.single = True
a_man = Person()
print(a_man.name)
print(a_man.age)
print(a_man.single)
zhangsan
18
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
C:\Users\name\AppData\Local\Temp/ipykernel_10428/3992591591.py in <module>
11 print(a_man.name)
12 print(a_man.age)
---> 13 print(a_man.single)
AttributeError: 'Person' object has no attribute 'single'
我们可以看到由于没有调用add_instance_val
这个方法,因此single
这个值没有被定义
a_man.add_instance_val()
print(a_man.single)
True
调用完add_instance_val
方法之后,就可以取到single
这个值了
例2
# 实例化对象
a = Person()
dir(a)
['__class__',
'__delattr__',
......
'__weakref__',
'add_instance_val',
'age',
'name']
我们可以看到实例化对象后,这个对象就有了name
,age
属性和add_instance_val
这个方法
a.add_instance_val()
dir(a)
['__class__',
'__delattr__',
......
'__weakref__',
'add_instance_val',
'age',
'name',
'single']
只有我们运行add_instance_val
实例方法之后,这个对象才有了single
属性
赋值
定义完实例之后,可以直接以instance.attribute = val
的格式进行赋值
注:通过类对象可以访问类变量,但无法修改类变量的值。
class Person:
salary = "100m"
def __init__(self):
self.name = "张三"
self.age = 18
def add_instance_val(self):
self.single = True
bb = Person()
print(bb.name)
print(bb.age)
# 修改属性
bb.name = "法外狂徒"
bb.age = 20
print("==========修改属性之后==========")
print(bb.name)
print(bb.age)
print("==========初始的类变量==========")
print(Person.salary)
print("==========尝试通过对象,修改类变量==========")
# 尝试修改
bb.salary = "1000m"
print("==========修改后的类变量==========")
print(Person.salary)
print("==========修改后的实例变量==========")
print(bb.salary)
张三
18
==========修改属性之后==========
法外狂徒
20
==========初始的类变量==========
100m
==========尝试通过对象,修改类变量==========
==========修改后的类变量==========
100m
==========修改后的实例变量==========
1000m
可以看到类变量并没有被修改
这是因为,通过类对象修改类变量的值,不是在给“类变量赋值”,而是定义新的实例变量。
显然,通过类对象是无法修改类变量的值的,本质其实是给bb
对象新添加了salary
这个实例变量
类中,实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因。
特性
- 和类变量不同,通过某个对象修改实例变量的值,不会影响类的其它实例化对象,更不会影响同名的类变量。例如:
class Person:
name = "类变量名字" # 类变量
def __init__(self):
self.name = "实例变量名字" # 实例变量
# 通过实例方法定义实例变量
def add_val(self):
self.catalog = 13 # 实例变量
# 定义两个实例
instance_a = Person()
instance_b = Person()
print("***修改类变量前***\n")
print(f"类变量Person.name为: {Person.name}")
print(f"instance_a实例变量instance_a.name为: {instance_a.name}")
print(f"instance_b实例变量instance_b.name为: {instance_b.name}")
print("\n***修改 instance_a 对象的实例变量***\n")
# 修改 instance_a 对象的实例变量
instance_a.name = "instance_a更换后的名字"
print(f"类变量Person.name为: {Person.name}")
print(f"instance_a实例变量instance_a.name为: {instance_a.name}")
print(f"instance_b实例变量instance_b.name为: {instance_b.name}")
***修改类变量前***
类变量Person.name为: 类变量名字
instance_a实例变量instance_a.name为: 实例变量名字
instance_b实例变量instance_b.name为: 实例变量名字
***修改 instance_a 对象的实例变量***
类变量Person.name为: 类变量名字
instance_a实例变量instance_a.name为: instance_a更换后的名字
instance_b实例变量instance_b.name为: 实例变量名字
局部变量
除了实例变量,类方法中还可以定义局部变量。和前者不同,局部变量直接以“变量名=值”的方式进行定义,例如:
class Employee:
# 定义increase_salary实例方法
def increase_salary(self, now_salary):
rate = 200
new_salary = rate * now_salary
print("加薪后的工资为:", new_salary)
zz = Employee()
zz.increase_salary(50000)
加薪后的工资为: 10000000
常情况下,定义局部变量是为了所在类方法功能的实现。需要注意的一点是,局部变量(上例中的rate
和new_salary
)只能用于所在函数中,函数执行完成后,局部变量也会被销毁。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步