page contents

类属性与实例属性的详解来啦!

无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们。我们可以将类看做一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数。

无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们。我们可以将类看做一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数。

在类体中,根据变量定义的位置不同,以及定义的方式不同,类属性又可细分为以下 2 种类型:

  1. 类体中、所有函数之外:此范围定义的变量,称为类属性类变量
  2. 类体中,所有函数内部:以“self.变量名”的方式定义的变量,称为实例属性实例变量

不仅如此,类方法也可细分为实例方法、静态方法和类方法。

那么,类变量、实例变量以及局部变量之间有哪些不同呢?接下来就围绕此问题做详细地讲解。

类变量(类属性)

类变量指的是在类中,但在各个类方法外定义的变量。举个例子:

  1. class Language :
  2. # 下面定义了2个类变量
  3. name = "百度网址"
  4. add = "https://www.baidu.com/"
  5. # 下面定义了一个say实例方法
  6. def say(self, content):
  7. print(content)

上面程序中,name 和 add 就属于类变量。

类变量的特点是,所有类的实例化对象都同时共享类变量,也就是说,类变量在所有实例化对象中是作为公用资源存在的。类方法的调用方式有 2 种,既可以使用类名直接调用,也可以使用类的实例化对象调用。

比如,在 Language 类的外部,添加如下代码:

  1. #使用类名直接调用
  2. print(Language.name)
  3. print(Language.add)
  4. #修改类变量的值
  5. Language.name = "Python官网"
  6. Language.add = "https://www.python.org/"
  7. print(Language.name)
  8. print(Language.add)

程序运行结果为:

百度网址
https://www.baidu.com/
Python官网
https://www.python.org/

可以看到,通过类名不仅可以调用类变量,也可以修改它的值。

当然,也可以使用类对象来调用所属类中的类变量(此方式不推荐使用,原因后续会讲)。例如,在 Language 类的外部,添加如下代码:

  1. lang = Language()
  2. print(lang.name)
  3. print(clang.add)

运行程序,结果为:

百度网址
https://www.baidu.com/

注意,因为类变量为所有实例化对象共有,通过类名修改类变量的值,会影响所有的实例化对象。例如,在 Language 类体外部,添加如下代码:

  1. print("修改前,各类对象中类变量的值:")
  2. lang1 = Language()
  3. print(lang1.name)
  4. print(lang1.add)
  5. lang2 = Language()
  6. print(lang2.name)
  7. print(lang2.add)
  8. print("修改后,各类对象中类变量的值:")
  9. Language.name = "Python官网"
  10. Language.add = "https://www.python.org/"
  11. print(lang1.name)
  12. print(lang1.add)
  13. print(lang2.name)
  14. print(lang2.add)

程序运行结果为:

修改前,各类对象中类变量的值:
百度网址
https://www.baidu.com/
百度网址
https://www.baidu.com/
修改后,各类对象中类变量的值:
Python官网
https://www.python.org/
Python官网
https://www.python.org/

显然,通过类名修改类变量,会作用到所有的实例化对象(例如这里的 lang1 和 lang2)。

注意,通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量(在讲实例变量时会进行详细介绍)。

值得一提的是,除了可以通过类名访问类变量之外,还可以动态地为类和对象添加类变量。例如,在 Language 类的基础上,添加以下代码:

  1. lang = Language()
  2. Language.catalog = 13
  3. print(lang.catalog)

运行结果为:

13

实例变量(实例属性)

实例变量指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。另外,实例变量只能通过对象名访问,无法通过类名访问。

举个例子:

  1. class Language :
  2. def __init__(self):
  3. self.name = "百度网址"
  4. self.add = "https://www.baidu.com/"
  5. # 下面定义了一个say实例方法
  6. def say(self):
  7. self.catalog = 13

此Language 类中,name、add 以及 catalog 都是实例变量。其中,由于 __init__() 函数在创建类对象时会自动调用,而 say() 方法需要类对象手动调用。因此,Language 类的类对象都会包含 name 和 add 实例变量,而只有调用了 say() 方法的类对象,才包含 catalog 实例变量。

例如,在上面代码的基础上,添加如下语句:

  1. lang = Language()
  2. print(lang.name)
  3. print(lang.add)
  4. #由于 lang 对象未调用 say() 方法,因此其没有 catalog 变量,下面这行代码会报错
  5. #print(lang.catalog)
  6. lang2 = Language()
  7. print(lang2.name)
  8. print(lang2.add)
  9. #只有调用 say(),才会拥有 catalog 实例变量
  10. lang2.say()
  11. print(lang2.catalog)

运行结果为:

百度网址
https://www.baidu.com/
百度网址
https://www.baidu.com/
13

前面讲过,通过类对象可以访问类变量,但无法修改类变量的值。这是因为,通过类对象修改类变量的值,不是在给“类变量赋值”,而是定义新的实例变量。例如,在 Language 类体外,添加如下程序:

  1. lang = Language()
  2. #lang访问类变量
  3. print(lang.name)
  4. print(clang.add)
  5. lang.name = "Python官网"
  6. lang.add = "https://www.python.org/"
  7. #lang实例变量的值
  8. print(lang.name)
  9. print(lang.add)
  10. #类变量的值
  11. print(Language.name)
  12. print(Language.add)

程序运行结果为:

Python官网
https://www.python.org/
Python官网
https://www.python.org/
Python官网
https://www.python.org/

显然,通过类对象是无法修改类变量的值的,本质其实是给 lang 对象新添加 name 和 add 这 2 个实例变量。

类中,实例变量和类变量可以同名,但这种情况下使用类对象将无法调用类变量,它会首选实例变量,这也是不推荐“类变量使用对象名调用”的原因。

另外,和类变量不同,通过某个对象修改实例变量的值,不会影响类的其它实例化对象,更不会影响同名的类变量。例如:

  1. class Language :
  2. name = "xxx" #类变量
  3. add = "http://" #类变量
  4. def __init__(self):
  5. self.name = "百度网址" #实例变量
  6. self.add = "https://www.baidu.com/" #实例变量
  7. # 下面定义了一个say实例方法
  8. def say(self):
  9. self.catalog = 13 #实例变量
  10. lang = Language()
  11. #修改 lang 对象的实例变量
  12. lang.name = "Python官网"
  13. lang.add = "https://www.python.org/"
  14. print(lang.name)
  15. print(lang.add)
  16. lang2 = Language()
  17. print(lang2.name)
  18. print(lang2.add)
  19. #输出类变量的值
  20. print(Language.name)
  21. print(Language.add)

程序运行结果为:

Python官网
https://www.python.org/
百度网址
https://www.baidu.com/
xxx
http://

不仅如此,Python 只支持为特定的对象添加实例变量。例如,在之前代码的基础上,为 clang 对象添加 money 实例变量,实现代码为:

  1. lang.money = 30
  2. print(lang.money)
  • 发表于 2021-05-29 22:03
  • 阅读 ( 595 )
  • 分类:Python开发

0 条评论

请先 登录 后评论
Cara
Cara

36 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章