Python - 面向对象编程 - 类变量、实例变量/类属性、实例属性

简介: Python - 面向对象编程 - 类变量、实例变量/类属性、实例属性

什么是对象和类


https://www.cnblogs.com/poloyy/p/15178423.html

 

什么是 Python 类、类对象、实例对象


https://www.cnblogs.com/poloyy/p/15178456.html

 

类变量、实例变量/类属性、实例属性


前言

只是叫法不一样

实例属性 = 实例变量

类属性 = 类变量

个人认为叫属性更恰当

 

类属性和实例属性区别

  • 类属性,所有实例对象共享该属性
  • 实例属性,属于某一个实例对象的属性,用于描述具体的对象

 

从实际栗子了解类属性、实例属性


有一个表格,四个常见的明星

姓名 年龄
周润发 58
成龙 55
刘德华 53
周星驰 54

总结一下

  • 四个人归类为明星
  • 每个明星都有两个属性:姓名、年龄
  • 明星这个群体具有一个属性:明星数量,在这张表是 4
  • 姓名和年龄等属性是用来描述具体的一个对象
  • 明星的数量是用于描述明星这个类别

 

使用面向对象编程思想来总结的话

  • 周润发、成龙、刘德华、周星驰都是实例对象
  • 他们都属于明星,明星是
  • 属于实例对象的属性有:姓名、年龄,所以也叫实例属性
  • 属于明星类的属性有:数量,所以也叫类属性

 

类里面的三种类型变量


  • 在所有方法之外定义的变量,称为类属性/类变量
  • 在方法内部,通过 self.变量名 方式定义的变量,称为实例属性/实例变量
  • 在方法内部,通过 变量名=变量值 方式定义的变量,称为局部变量

 

类属性


类属性在类中的定义

class 类名:
    类属性1 = 值
    类属性2 = 值
    def func(self): 
        ...        


类属性、类方法注意点

  • 无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们(类方法后面详解)
  • 可以将类看做一个独立的空间,类属性其实也是在类体中定义的变量,类方法是在类体中定义的函数
  • 需要通过类对象/实例对象来调用类属性 ClassName.classProperty (类方法后面详解)

 

类属性的栗子

# 类属性
class PoloBlog:
    # 这就是在所有方法之外 下面定义了 2 个类变量
    name = "小菠萝测试笔记"
    blog = "https://www.cnblogs.com/poloyy/"
# 通过类名调用类属性
print(PoloBlog.name)
print(PoloBlog.blog)
# 输出结果
小菠萝测试笔记
https://www.cnblogs.com/poloyy/


通过 Pycharm 的代码联想,可以看到 blog、name、__doc__ 三个类属性

image.png

类属性的调用方式

有两种

  • 直接通过类名调用
  • 也可以通过类的实例对象调用

 

调用类属性的栗子

# 调用类属性的两种方式
class PoloBlog:
    # 这就是在所有方法之外 下面定义了 2 个类变量
    name = "小菠萝测试笔记"
    blog = "https://www.cnblogs.com/poloyy/"
# 通过类名直接调用
print(PoloBlog.name)
print(PoloBlog.blog)
# 修改类属性
PoloBlog.name = "blogyuan"
PoloBlog.blog = "https://www.cnblogs.com/"
# 通过实例对象调用修改后的类属性
poloBlog = PoloBlog()
print(poloBlog.name)
print(poloBlog.blog)
# 输出结果
小菠萝测试笔记
https://www.cnblogs.com/poloyy/
blogyuan
https://www.cnblogs.com/


通过类名修改类属性的值,会影响所有的实例化对象

 

实例对象修改类属性

# 修改类属性
poloBlog.name = "小菠萝回来了"
# 再看看类对象调用修改后的类属性
print(PoloBlog.name)
print(poloBlog.name)
# 输出结果
blogyuan
小菠萝回来了


  • 会发现,类名.name 仍然返回之前的值,而 实例对象.name 会返回修改的值
  • 原因: 实例对象.name 本质上并不是修改类属性的值,而是在定义一个新的实例属性(下面详解)

 

动态添加类属性

PoloBlog.age = 24
print(PoloBlog.age)
print(poloBlog.age)
# 输出结果
24
24


  • age 没有在类体中定义
  • 可以直接通过 类名.new_property_name 的方式定义一个新的类属性

 

实例属性


  • 属于具体对象的属性,用于描述具体的对象
  • 只能通过实例对象访问,无法通过类名访问

 

实例属性的栗子

class PoloBlog:
    def __init__(self):
        # 在方法内部,通过 self.name 的方式定义的变量就是实例变量
        self.name = "小菠萝测试笔记"
        self.add = "https://www.cnblogs.com/poloyy/"
    # 下面定义了一个 say 实例方法
    def say(self):
        self.age = 13
# 实例化对象
blog = PoloBlog()
blog.say()
print(blog.name, blog.add, blog.age)
# 输出结果
小菠萝测试笔记 https://www.cnblogs.com/poloyy/ 13


  • 重点:__init__ 会在实例化对象的时候自动调用,因此 blog 创建成功就有 name、add 两个实例属性
  • 调用 say() 方法之后才有第三个实例属性 age

 

修改实例属性的栗子

blog.name = "小菠萝"
blog.add = "xiaopolo.com"
blog.age = 24
print(blog.name, blog.add, blog.age)
# 输出结果
小菠萝 xiaopolo.com 24



动态添加实例属性

blog.phone = 13501489999
print(blog.phone)
# 输出结果
13501489999


上面也有说到,通过 实例对象.属性名 的方式并不会给类变量赋值,而是定义一个新的实例变量

 

综合栗子

# 综合栗子
class PoloBlogObjectTest:
    # 类变量
    sum = 0
    # 初始化方法
    def __init__(self, name, age):
        # 实例变量
        self.name = name
        self.age = age
        # 类变量
        PoloBlogObjectTest.sum += 1
    # 实例方法
    def printNameAge(self):
        print(self.name, self.age)
poloTest1 = PoloBlogObjectTest("小菠萝一号", 24)
poloTest2 = PoloBlogObjectTest("小菠萝二号", 14)
print(PoloBlogObjectTest.sum)
# 调用实例方法
poloTest1.printNameAge()
poloTest2.printNameAge()
# 输出结果
2
小菠萝一号 24
小菠萝二号 14


不推荐实例属性和类属性同名


  • 类中,实例属性和类属性可以同名
  • 但这种情况下使用实例对象将无法调用类变量,它会首选实例变量,无论这个变量是否已定义
  • 实例独享绑定新的实例属性时,会直接覆盖掉重名的类属性

 

实例属性、类属性同名栗子

class Person:
    # 只有一个类变量
    name = "cool guy"
# 实例化一个对象
p = Person()
# 打印实例属性 name,因为实例对象并没有name属性,所以会继续查找class的name属性
print(p.name)
# 打印类属性 name
print(Person.name)
# 给实例绑定 name、age 属性
p.name = "bad guy"
p.age = 12
# 打印 name、age 属性
print(p.age)
# 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的 name 属性
print(p.name)
# 仍然打印类的 name 属性
print(Person.name)
# 输出结果
cool guy
cool guy
12
bad guy
cool guy


实例对象属性引用的查找过程


image.png

相关文章
|
5天前
|
存储 Python 容器
python之变量的使用
Python 中变量是对象的引用,赋值即为指向内存中对象。创建对象时,解释器分配内存,引用计数管理内存回收。Python 是动态类型语言,变量类型在运行时确定。对象分为可变与不可变,前者可修改内部状态,后者则不行。命名空间管理变量作用域,确保不同区域的变量独立。
|
1月前
|
物联网 Python
请问:如何使用python对物联网平台上设备的属性进行更改?
为验证项目可行性,本实验利用阿里云物联网平台创建设备并定义电流、电压两个整型属性。通过Python与平台交互,实现对设备属性的控制,确保后续项目的顺利进行。此过程涵盖设备连接、数据传输及属性调控等功能。
|
2月前
|
Python
[oeasy]python050_如何删除变量_del_delete_variable
本文介绍了Python中如何删除变量,通过`del`关键字实现。首先回顾了变量的声明与赋值,说明变量在声明前是不存在的,通过声明赋予其生命和初始值。使用`locals()`函数可查看当前作用域内的所有本地变量。进一步探讨了变量的生命周期,包括自然死亡(程序结束时自动释放)和手动删除(使用`del`关键字)。最后指出,删除后的变量将无法在当前作用域中被访问,并提供了相关示例代码及图像辅助理解。
126 68
|
1月前
|
人工智能 Unix Java
[oeasy]python059变量命名有什么规则_惯用法_蛇形命名法_name_convention_snake
本文探讨了Python中变量命名的几种常见方式,包括汉语拼音变量名、蛇形命名法(snake_case)和驼峰命名法(CamelCase)。回顾上次内容,我们主要讨论了使用下划线替代空格以提高代码可读性。实际编程中,当变量名由多个单词组成时,合理的命名惯例变得尤为重要。
80 9
|
2月前
|
存储 数据处理 Python
Python如何显示对象的某个属性的所有值
本文介绍了如何在Python中使用`getattr`和`hasattr`函数来访问和检查对象的属性。通过这些工具,可以轻松遍历对象列表并提取特定属性的所有值,适用于数据处理和分析任务。示例包括获取对象列表中所有书籍的作者和检查动物对象的名称属性。
43 2
|
2月前
|
Shell Python
[oeasy]python049_[词根溯源]locals_现在都定义了哪些变量
本文介绍了Python中`locals()`函数的使用方法及其在调试中的作用。通过回顾变量赋值、连等赋值、解包赋值等内容,文章详细解释了如何利用`locals()`函数查看当前作用域内的本地变量,并探讨了变量声明前后以及导入模块对本地变量的影响。最后,文章还涉及了一些与“local”相关的英语词汇,如`locate`、`allocate`等,帮助读者更好地理解“本地”概念在编程及日常生活中的应用。
44 9
|
3月前
|
Python
Python三引号用法与变量详解
本文详细介绍了Python中三引号(`"""` 或 `'''`)的用法,包括其基本功能、如何在多行字符串中使用变量(如f-string、str.format()和%操作符),以及实际应用示例,帮助读者更好地理解和运用这一强大工具。
150 2
|
3月前
|
机器学习/深度学习 存储 数据挖掘
Python 编程入门:理解变量、数据类型和基本运算
【10月更文挑战第43天】在编程的海洋中,Python是一艘易于驾驭的小船。本文将带你启航,探索Python编程的基础:变量的声明与使用、丰富的数据类型以及如何通过基本运算符来操作它们。我们将从浅显易懂的例子出发,逐步深入到代码示例,确保即使是零基础的读者也能跟上步伐。准备好了吗?让我们开始吧!
52 0
|
9月前
|
Java 程序员 Python
python学习13-面向对象的三大特征、特殊方法和特殊属性、类的浅拷贝和深拷贝
python学习13-面向对象的三大特征、特殊方法和特殊属性、类的浅拷贝和深拷贝
29.从入门到精通:Python3 面向对象继承 多继承 方法重写 类属性与方法
29.从入门到精通:Python3 面向对象继承 多继承 方法重写 类属性与方法

热门文章

最新文章