Python中的实例变量和类变量

本文深入探讨了Python中变量类型的两大类别:不可变类型(如数字、字符串和元组)与可变类型(如列表和字典)。重点分析了可变类型在Python中的使用及其可能引起的别名问题,并通过具体的实例演示了实例变量与类变量的区别。

此博客参考了部分资料,具体链接在下方。

# 首先我们要知道变量分为 immutable 和 mutable
# imutable types : numbers, strings, tuples..
# mutable types  : lists, dictionaries...
# 其中在Pytion中使用 mutable types 可能会引起 aliasing

class Dog:
    # 类变量
    kind = 'canine' # immutable
    tricks = [] # mutable

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

a = Dog('a')
b = Dog('b')
c = Dog('c')

# 通过一个对象a访问一个变量x,变量的查找过程是这样的:
# 先在对象自身的__dict__中查找是否有x,如果有则返回,否则
# 进入对象a所属的类A的__dict__中进行查找
# 例如:

a.kind # 结果返回 'canine'

# 对象a试图修改一个属于类的immutable的变量,则python会在内存中为对象a
# 新建一个kind变量,此时a就具有了属于自己的kind变量
a.kind = 'unknown'

a.__dict__   # {'kind': 'unknow', 'name': 'a'}
b.__dict__   # {'name': 'b'}
Dog.__dict__ # 'kind': 'canine','tricks': []

# 对象b试图修改一个mutable的变量tricks,
# 但是直接用一个列表lis(在内存中有自己的地址)赋值,并不会去访问类变量中的tricks,
# python会直接为对象b新建一个tricks变量并和lis指向同一个地址
lis = ['run','sit']
id(lis)      # 内存地址:1527988934728

b.tricks = lis
id(b.tricks) # 内存地址:1527988934728

b.__dict__   # {'name': 'b', 'tricks': ['run', 'sit']}
a.__dict__   # {'kind': 'unknow', 'name': 'a'}
Dog.__dict__ # 'kind': 'canine','tricks': []

# 对象c也试图修改一个mutable的变量,但在c中找不到该变量,
# 则python找到类Dog的__dict__中的变量tricks,
# 类Dog以及它的实例(__dict__中没有变量tricks的)都公用一个tricks
c.tricks.append('run')

c.__dict__   # {'name': 'c'}
a.__dict__   # {'kind': 'unknow', 'name': 'a'}
Dog.__dict__ # 'kind': 'canine','tricks': [run]

# 在编写程序的时候,实例变量和类变量请不要使用相同的名字
# 相同名称的实例变量将屏蔽掉类变量
# 使用类变量的时候也要注意 aliasing

参考资料:

Python中的aliasing
Python:Immutable vs Mutable types
官方教程 - python3.5 Docs
廖雪峰 - 实例属性和类属性
python的类变量与实例变量以及__dict__属性

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值