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

news2024/11/28 22:39:17

什么是对象和类

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

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

前言

只是叫法不一样

实例属性 = 实例变量

类属性 = 类变量

个人认为叫属性更恰当

类属性和实例属性区别

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

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

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

姓名

年龄

周润发

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__ 三个类属性

类属性的调用方式

有两种

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

调用类属性的栗子

# 调用类属性的两种方式
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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/572681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win10系统如何设置虚拟回环

在日常生活中,人们(特别是IT行业者)通常需要在一台机上进行软件测试,而同一台计算上通常只能使用一个地址,而在需要同时使用两个地址进行测试的时候就显得捉襟见肘。此方法通过配置window10自带的环回适配器,达到上述目的。 win1…

如何用chatgpt写作论文 GPT写毕业论文的技巧

如何用chatgpt写作论文 GPT写论文的技巧 经常被问到为什么万事知天下小程序不能写论文。也不是不能写,只是GPT3.5的上下文只有4K,一般论文要写上万字,所以不可能你直接输入一个论文标题就直出结果的。 不过手工分一下步骤就可以了。先让写…

适用于中小企业的5种采购策略

与大企业不同,在采购管理方面,中小企业往往不得不在更有限的资源范围内运作,并且没有同等水平的经验丰富的采购专业人员或先进的采购技术。这会使优化采购流程并实现与大型企业相同水平的成本节约和风险管理变得更具挑战性。但是,…

docker idea直接部署到腾讯云镜像服务

首先创建一个Dockerfile 编写Dockerfile的信息 FROM java:8 MAINTAINER clarkshixxx.com RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo Asia/Shanghai >/etc/timezone ENV ACTIVE"pre" ENV loggingpath"/zhibo/logs"…

【Flutter 工程】005-代码分离实践:flutter_hooks functional_widget

【Flutter 工程】005-代码分离实践:flutter_hooks & functional_widget 文章目录 【Flutter 工程】005-代码分离实践:flutter_hooks & functional_widget一、概述1、Flutter “嵌套地狱”2、代码分离实践 二、实践1、安装 flutter_hooks & f…

油猴脚本尝试

现在是这样的,我这边有个运维系统,里面有个日志,我们经常要复制,然后我们复制的时候需要打开内容,然后去选中复制。 类似于这种,我觉得这个时候,去选中复制就很麻烦,右边这里不是有…

ChatGPT四大基本使用场景分析

ChatGPT是一种基于深度神经网络的自然语言生成模型,它能够通过大量的数据训练和学习,以模拟人类的自然语言交互方式来理解和回答用户提出的问题。作为一种全新的人工智能技术,ChatGPT具有高度的灵活性和可扩展性,可以不断地优化、…

Redis BigKey问题

1.广告平台,海量数据查询固定前缀的key 不要使用keys , 使用 scan 命令 scan 0 match "user:" 10 2.Memory usage命令用过吗 memory usage key [semples count] :计算每个键值对的字节数 3.bigKey 问题,多大算bigKey,如何发现?如何处理?如…

【Linux】打开Linux大门,踏入Linux世界(环境搭建再加一群Linux基本指令就OK啦~)

🧑‍🎓个人主页:简 料 🏆所属专栏:Linux系统编程与网络编程 🏆个人社区:越努力越幸运社区 🏆简 介:简料简料,简单有料~在校大学生一枚&#x…

论文分享 | 视野约束下多机器人系统的最小持久图生成与编队控制

阿木推出的Prometheus项目校园赞助活动,再次迎来开发者参与! 北京理工大学自动化学院赵欣悦同学,在Prometheus开源仿真架构的基础上进行了二次开发,且使用P450进行了真机实验并发表了相关论文,其论文《视野约束下多机…

前端开发如何速成java,使用java开发网络接口

引言 我是干前端的,闲来没事,也想学学java,下面我会根据我学习java的经历来整理出java的速成之路。 学习路线 按照数字的顺序学下去就行了 1.学习java基础教程:主要听 class和集合这两部分吧,这两个部分非常重要&am…

ASEMI代理韩景元可控硅C106M参数,C106M封装,C106M尺寸

编辑-Z 韩景元可控硅C106M参数: 型号:C106M 断态重复峰值电压VDRM:600V 通态电流IT(RMS):4A 通态浪涌电流ITSM:30A 平均栅极功耗PG(AV):0.2W 峰值门功率耗散PGM:1W 工作接点温度Tj&…

【LeetCode】《LeetCode 101》第九章:巧解数学问题

文章目录 9.1 公倍数与公因数9.2 质数204.计数质数(中等) 9.3 数字处理504. 七进制数(简单)172. 阶乘后的零(中等)415. 字符串相加(简单)326. 3 的幂(简单) 9…

mysql语句最大执行时间问题解决,无需改mysql配置

下面是我排错的一个过程: 1、我是ado.net执行一个查询语句报了个错: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 译:超时已过期。操作完成前经过的超时时间&a…

【Netty】 工作原理详解(十一)

文章目录 前言一、Netty 模型二、代码示例2.1、引入Maven依赖2.2、服务端的管道处理器2.3、服务端主程序2.4、客户端管道处理器2.5、客户端主程序2.6、测试运行 总结 前言 回顾Netty系列文章: Netty 概述(一)Netty 架构设计(二&…

借军工经验开拓消费市场,三星显示收购eMagin浅析

前不久三星显示(Samsung Display)宣布,拟支付2.18亿美元收购微显示方案商eMagin全部普通股,收购完成后eMagin将并入三星显示,以加速XR显示业务发展。 据青亭网了解,eMagin成立于1996年,该公司多…

《Spring Guides系列学习》guide11 - guide15

要想全面快速学习Spring的内容,最好的方法肯定是先去Spring官网去查阅文档,在Spring官网中找到了适合新手了解的官网Guides,一共68篇,打算全部过一遍,能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gu…

JVM调优实战

1、当项目运行一段时间以后,产生了OOM的问题,我们该如何排查问题呢? 用top命令,看看是哪个进程CPU占用率高,获取它的进程ID,再根据具体的进程id,执行 top -HP 进程id号 命令,看看哪个线程的CP…

复制架构,Redis Sentinel分析

存储高可用,一般采用复制架构,复制架构,需要关注故障架构和状态决策2个要点 复制架构通用关注点 数据复制 复制格式 格式优点缺点举例命令数据量小可能存在数据不一致Mysql 的statement同步方式,按commit顺序同步,…

文件系统考古:1974-Unix V7 File System

有时,进步难以察觉,特别是当你正身处其中时。而对比新旧资料之间的差异,寻找那些推动变革的信息源,我们就可以清晰地看到进步的发生。在Linux(以及大部分Unix系统)中,都可以印证这一点。 Unix …