【转载】Python 中的类变量和实例变量

因为本文参考的文章较多,csdn无法在原文链接处填写多个链接,故此处仅填写一个链接,将所有参考文章的链接全部放在了文章最后。

1.概念

类变量:定义在类中,但是在函数体之外的变量。通常不使用self.变量名赋值的变量。类变量通常不作为类的实例变量,类变量对于所有实例化的对象中是公用的。
实例变量:定义在方法中的变量,使用self绑定到实例上的变量,只是对当前实例起作用。

2.访问

先来看一个代码

class Student():
   name = "Marry Liu"    # 类变量
   age = 0    # 类变量

   def __init__(self, name, age):
         name = name  # 局部变量
         age = age


s = Student('Carrie', 19)
print s.name, s.age
print Student.name, Student.age

print s.__dict__
print Student.__dict__

结果:

Marry Liu 0
Marry Liu 0
{}
{‘age’: 0, ‘module’: ‘main’, ‘name’: ‘Marry Liu’, ‘init’: <function init at 0x7fc02518b668>, ‘doc’: None}

这里我们要说一下实例变量的查找机制:
当在实例变量中查找不到某一变量时候,就会去类变量里查找,当再查找不到的时候就会在父类中查找,因此输出的name为Marry Liu, 而不是Carrie。s的内容之所以为空,是因为我们实例化对象的时候为指明实例变量的保存。

下面更改一下代码:

class Student():
   name = "Marry Liu"  # 类变量
   age = 0  # 类变量

   def __init__(self, name, age):
         self.name = name  # 实例变量
         self.age = age


s = Student('Carrie', 19)
print s.name, s.age
print Student.name, Student.age

print s.__dict__
print Student.__dict__

结果:

Carrie 19
Marry Liu 0
{‘age’: 19, ‘name’: ‘Carrie’}
{‘age’: 0, ‘module’: ‘main’, ‘name’: ‘Marry Liu’, ‘init’: <function init at 0x7f0d73606668>, ‘doc’: None}

我们传入的self只和实例化的对象有关和类无关,代表实例。

访问规则:

  1. 类变量可以通过“类名.类变量名”、“实例名.类变量名”两种方式读取,即类和实例都能读取类变量。
class Student():
   name = "Marry Liu"  # 类变量
   age = 0  # 类变量

   def __init__(self, major):
         self.major = major  # 实例变量


s = Student('Computer Science')
print s.name, s.age
print Student.name, Student.age

print s.__dict__
print Student.__dict__

结果:

Marry Liu 0
Marry Liu 0
{‘major’: ‘Computer Science’}
{‘age’: 0, ‘module’: ‘main’, ‘name’: ‘Marry Liu’, ‘init’: <function init at 0x7f6d4efda668>, ‘doc’: None}

  1. 实例变量只能通过“实例名.实例变量名”的方式访问,类无权访问实例名。
class Student():
   name = "Marry Liu"  # 类变量
   age = 0  # 类变量

   def __init__(self, major):
         self.major = major  # 实例变量


s = Student('Computer Science')
print s.major
print Student.major

print s.__dict__
print Student.__dict__

结果:

Computer Science
Traceback (most recent call last):
File “/home/maqian/Algrithom/JianZhi_offer/ttttt.py”, line 21, in
print Student.major
AttributeError: class Student has no attribute ‘major’

  1. “类名.类变量名”、“实例名.类变量名”访问的实际上是同一个命名空间的变量,所以类变量具有“一改全改”的特点。
class Student():
   name = "Marry Liu"  # 类变量
   age = 0  # 类变量

   def __init__(self, major):
         self.major = major  # 实例变量


s = Student('Computer Science')
print s.name, s.age, s.major
print Student.name, Student.age

print s.__dict__
print Student.__dict__

print "----------------------"
Student.name = 'Penny'
Student.age = 21

print s.name, s.age, s.major
print Student.name, Student.age

print s.__dict__
print Student.__dict__

结果:

Marry Liu 0 Computer Science
Marry Liu 0
{‘major’: ‘Computer Science’}
{‘age’: 0, ‘module’: ‘main’, ‘name’: ‘Marry Liu’, ‘init’: <function init at 0x7f1908e87668>, ‘doc’: None}
----------------------
Penny 21 Computer Science
Penny 21
{‘major’: ‘Computer Science’}
{‘age’: 21, ‘module’: ‘main’, ‘name’: ‘Penny’, ‘init’: <function init at 0x7f1908e87668>, ‘doc’: None}

  1. 采用‘实例名.类变量名’的方式对类变量进行赋值时,若该类变量是可变数据类型,则可以成功赋值该类变量,否则会在该实例变量所在的名称空间中创建一个与该类变量同名的实例变量进行赋值,并不会对类变量进行赋值,此时也无法再通过‘实例名.类变量名’的方式读取该类变量。但若‘实例名.类变量名’赋值的是可变数据类型,则可以对类变量进行赋值操作。
class Student():
   name = "Marry Liu"  # 类变量
   age = 0  # 类变量
   place = ['China', 'Beijing']

   def __init__(self, major, name):
       self.name = name
       self.major = major  # 实例变量


s = Student('Computer Science', 'Lily Liu')
print s.name, s.age, s.place, s.major
print Student.name, Student.age, Student.place
s.place[1] = 'Shanghai'
print s.name, s.age, s.place, s.major
print Student.name, Student.age, Student.pla

结果:

Lily Liu 0 [‘China’, ‘Beijing’] Computer Science
Marry Liu 0 [‘China’, ‘Beijing’]
Lily Liu 0 [‘China’, ‘Shanghai’] Computer Science
Marry Liu 0 [‘China’, ‘Shanghai’]

参考:
  1. https://www.jianshu.com/p/8b2cd55ae37a
  2. https://blog.csdn.net/chb4715/article/details/79104376
  3. https://www.jianshu.com/p/9fefb52ca91b
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值