构造函数&类属性和实例属性&析构函数

2023-11-16

1、构造函数

  • 概念:构造函数包括__new__和__init__
  • 构造函数,也被称为构造器,指的是当创建对象的时候,被自动调用的函数
  • 注意:在Python中,以__xxx__方式命名的函数被称为魔术函数/魔术方法,这类函数在使用的时候无需手动调用,在进行某个操作的时候会自动调用
  • init)说明:先创建对象,然后使用直接赋值【动态绑定属性】方式给对象绑定属性,可以使用,但是代码比较繁杂,一般情况下,很多类倾向于将对象创建为有初始状态的,常规用法中,在类中可以定义一个函数,名称为__init__,该特殊的函数被称为构造函数,主要用于给对象的数据做出初始化
#语法:
'''
def __new__(cls,*args,**kwrags):
	pass
def __init__(self):
    pass
'''
#1、《介绍构造函数:__init__》(使对象初始化(绑定属性)变简单)
# class Man():
#     __slots__ = ('house','money','power')
#
# zhang_san = Man()
# man.house = '无'
# man.money = '无'
# man.power = '无'
#
# li_si = Man()
# li_si.house = "有"
# li_si.money = '无'
# li_si.power = '无'

#可以看出上面定义对象的过程是比较繁琐的

class Man():
    __slots__ = ('house','money','power')
    def __init__(self,power):
        self.house = '无'
        self.money = '无'
        self.power = power  #如果需要创建对象的时候传参,则设置形参
        print('__init__~~')

zhang_san = Man('无')
print('zhang_san(房子、钱、力量):',zhang_san.house,zhang_san.money,zhang_san.power)

li_si = Man('100000磅')
print('li_si(房子、钱、力量):',li_si.house,li_si.money,li_si.power)
'''
执行结果:
__init__~~
zhang_san(房子、钱、力量): 无 无 无
__init__~~
li_si(房子、钱、力量): 无 无 100000磅
总结:
    a.当创建对象的时候,会自动调用__init__,(和其他类中函数一样,__init__中的self表示当前对象)
    b.在__init__中动态绑定属性,如果需要创建对象的时候传参,则设置形参(且约定名字和属性名一致),如果不需要传参,则可以直接定义
    c.如果需要给对象动态绑定属性,为了代码的可读性和后期的可维护性,一般将动态属性的绑定书写在__init__中!(对象初始化变简单)
    d.当给__init__设置了和属性相关的参数之后,当创建对象的时候,一定要注意参数的匹配(设置形参的,必须在创建对象的时候传参)
'''

#2、《介绍构造函数:__new__》
# 【面试题】构造函数的工作原理
class Animal():
    __slots__ = ('name','age')
    def __new__(cls, *args, **kwargs):
        print("new~~~~~~~")
        # super().__new__(cls)表示创建对象
        return super().__new__(cls)
    def __init__(self,name,age):
        print("init~~~",id(self))
        self.name = name
        self.age = age

a = Animal("大黄",4)
print(a)   # <__main__.Animal object at 0x1043e6cd0>
print(id(a))

"""
总结:
    a.真正意义上,构造函数包含__new__和__init__
    b.在实际开发中,常用__init__,因为就算__new__在类中没有定义,当创建对象的时候仍然会自动调用
    c.__new__:表示创建对象,该函数的返回值就是创建出来的对象
        例如:a = Animal("大黄",4),a指向__new__的返回值
      __init__:表示初始化对象,系统会自动将__new__的返回值【创建的对象】会自动传参给__init__中的self,
               同时,将需要初始化的值传参给__init__中的其他参数,完成对象初始化的过程
    d.构造函数中,当创建对象的时候,都是先调用__new__,然后才调用__init__
"""

2、类属性和实例属性

  • 【面试题】简述类属性【类的字段】和实例属性【对象属性,对象的字段】的区别
    • 1.定义位置不同:类属性直接定义在类中,实例属性定义在init中或在类的外面直接动态绑定定义
    • 2.访问方式不同:类属性可以通过类名或对象访问,而实例属性只能通过对象访问
    • 3.访问优先级不同:当类属性和实例属性重名时,通过对象访问,优先访问的是实例属性
    • 4.在内存中出现的时机不同:类属性优先于实例属性出现在内存中,类属性随着类的加载而出现,实例属性是对象创建完毕之后才会出现
    • 5.使用场景不同:类属性用于表示多个对象共享的数据,实例属性表示每个对象特有的数据
#1、类属性和实例属性的区别
# 1.1.定义位置:类属性直接定义在类中,实例属性定义在__init__中或在类的外面直接动态绑定定义
# 1.2.访问方式:类属性可以通过类名或对象访问,而实例属性只能通过对象访问
# 1.3.访问优先级不同:当类属性和实例属性重名时,通过对象访问,优先访问的是实例属性
# 1.4.在内存中出现的时机不同:类属性优先于实例属性出现在内存中,类属性随着类的加载而出现,实例属性是对象创建完毕之后才会出现
# 1.5.使用场景不同:类属性用于表示多个对象共享的数据,实例属性表示每个对象特有的数据
class A_603():
    name = '603宿舍'  #类属性
    gender = '男'
    def __init__(self,name,age):
        self.name = name    #实例属性
        self.age = age  #实例属性
zhang = A_603('zhang_san',18)
zhang.hobby = '购物'  #实例属性
zhao = A_603('zhao_si',20)
print(f'验证1.2:{A_603.name},{zhang.age}')  # 验证1.2:603宿舍,18
print(f'验证1.3:{A_603.name},{zhang.name}')  # 验证1.3:603宿舍,zhang_san
print(f'验证1.5:{A_603.gender},{zhang.gender},{zhao.gender}')  # 验证1.5:男,男,男

#注意1:通过对象名没法修改类属性,只有通过类名才能修改类属性(注意有时候虽然类属性和对象属性重名,但是要当做两个不同的属性对待)
zhang.gender = '女'
print(f'验证:{A_603.gender},{zhang.gender},{zhao.gender}')  # 验证:男,女,男
zhang.gender = '男'
A_603.gender = '女'
print(f'验证:{A_603.gender},{zhang.gender},{zhao.gender}')  # 验证:女,男,女
'''
(注意,上面的print中,_603.gender和zhao.gender访问的是类属性,zhang.gender访问自己的对象属性)
'''
#注意2:类属性和实例属性重名,修改实例属性,类属性不变,要修改类属性,需要单独修改!
print(f'zhang.name:{zhang.name},_603.name:{A_603.name}') # zhang.name:zhang_san,_603.name:603宿舍
zhang.name = 'zhang_si'
print(f'zhang.name:{zhang.name},_603.name:{A_603.name}') # zhang.name:zhang_si,_603.name:603宿舍
A_603.name = '666宿舍'
print(f'zhang.name:{zhang.name},_603.name:{A_603.name}') # zhang.name:zhang_si,_603.name:666宿舍
#结论1:不同对象访问同一个类属性,访问的是同一份内存空间,通过 类名.属性 = 值 修改类属性,一旦被修改所有对象访问到的类属性结果都会随着修改
#结论2:不同对象的同名的实例属性,在内存中是不同的内存空间,一个发生修改,对另一个没有任何影响
#结论3:类和对象属性虽然同名,但也是两个不同内存空间,一个发生改变,另一个不变
print('*'*30)

3、析构函数

构造函数 析构函数
类中new函数创建对象,类中init函数初始化对象 类中del函数在对象结束生命周期时调用,用来释放内存
#1、析构函数
class Person():
    def __init__(self):
        print("构造函数被调用了")
    def __del__(self):
        print("析构函数被调用了~~~~~")
# 1.当对象被定义为全局变量,当程序结束之后,__del__会被自动调用 (注意,测试下面代码时,其他代码要注释掉,否则‘析构函数’在代码结束执行)
# print("start")
# p1 = Person()
# print("over")
"""
执行结果:
start
构造函数被调用了
over
析构函数被调用了~~~~~
"""
print('*'*30)

# 2.当对象被定义为局部变量,当函数调用完毕,__del__会被自动调用
def func():
    p2 = Person()
print("start")
func()
print("over")
"""
执行结果:
start
构造函数被调用了
析构函数被调用了~~~~~
over
"""
print('*'*30)

# 3.当对象被del删除,则__del__会被自动调用
print("start")
p3 = Person()
del p3
print("over")
"""
执行结果:
start
构造函数被调用了
析构函数被调用了~~~~~
over
"""
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构造函数&类属性和实例属性&析构函数 的相关文章

随机推荐

  • SpringBoot添加过滤器详解

    目录 一 过滤器详解 二 SpringBoot 添加过滤器 一 过滤器详解 过滤器 Filter 是 Java Web 应用中的一种重要组件 用于对请求和响应进行拦截和处理 它可以用于执行各种任务 如请求预处理 请求和响应的转换 授权检查
  • CSS Day03

    1 相对定位 relative 相对于原来位置移动 元素设置此属性之后仍然处在文档流中 不影响其他元素的布局 菜鸟教程
  • React框架学习笔记

    React系列知识点 一 项目初始化 1 react script 2 TSX 3 组件化 配置React的CSS模组 1 使用React最大的优势是模组化 CSS module 2 TS的定义声明 3 css类型声明 4 CSS in J
  • APP自动化测试-3. Appium元素定位与等待

    APP自动化测试 3 Appium元素定位与等待 文章目录 APP自动化测试 3 Appium元素定位与等待 前言 一 Appium Desired Capabilities简介 1 Appium Desired Capabilities通
  • 2022年天梯赛-全国总决赛 L2-1 插松枝 (25 分)

    又来补题了哎哎哎 考试的时候卡了一小时就离谱 include
  • c#之泛型

    using System using System Collections Generic using System Linq using System Text using System Threading Tasks namespace
  • 前端 立体照片demo

    地址 https www cnblogs com zyrblog p 11142624 html
  • The Stable Marriage Problem 【HDU - 1914】【稳定婚姻匹配问题】

    题目链接 Problem Description The stable marriage problem consists of matching members of two different sets according to the
  • springBoot+AOP收集日志信息,自定义接口实现日志收集

    之前做的ELK日志分析 没有收集到日志 都 是一些没有规则的输出 提取数据也相对复杂 今天 有时间就稍微实现了一下利用SpringBoot Aop的方式打印想要的数据格式 第一步 自定义接口 ElementType 参数里可以指定注入的位置
  • vscode检查python语法

    安装格式化工具 打开命令行窗口安装以下工具 pip install U flake8 pip install U autopep8 在VScode配置中打开首选项 gt 设置 搜索python linting flake8enabled 安
  • 信息安全工程实践笔记--Day2 暴力破解

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 实验目标 一 弱口令分类 1 系统服务弱口令 2 设备弱口令 3 社工型的弱口令 二 弱口令的攻击方式 暴力破解获取密码的方式 三 bp实操 1 bp模块讲解 1
  • opencv中的cv::ximgproc::SuperpixelSLIC,cv::ximgproc::SuperpixelSEEDS,SuperpixelLSC是超像素算法的

    可以研读下源码 集成到建筑物提取中
  • WorkPlus打造智慧企业移动门户,开启高效办公新时代

    在移动互联网时代 企业对于高效办公和便捷访问的需求不断增长 WorkPlus作为领先的品牌 致力于打造智慧企业移动门户 帮助企业实现高效协作与便捷访问 本文将重点介绍WorkPlus如何通过创新解决方案 为企业提供定制化的智慧移动门户 提升
  • kotlin.text.charsets

    java lang NoClassDefFoundError didn t find class kotlin text charsets Android studio项目中引入了自己下载的两个jar 3 10版本的okhttp和2 0版本
  • jQuery调用接口获取城市天气信息

    jQuery调用接口获取城市天气信息 代码如下
  • idea项目提交git报错bad revision ‘head‘

    报错 bad revision head 新建了一个文件夹 将后端项目 前端项目都放到这个文件夹里面去了 然后想提交git VCS gt import into Version control gt Create git Repositor
  • python中的pip、anaconda换国内源图文解析

    一 python中的pip换源 pip的源换成国内的源 1 首先在C Users 用户 自己的用户名目录下新建一个文件夹pip 2 之后在pip文件夹下新建一个pip txt 里边设置好国内的源 保存后改名为pip ini 文件内的内容如下
  • java中找不到符号是什么意思_JAVA小白入门很难发现的错误

    紧跟着上一篇文章 如何编写JAVA小白第一个程序 首先我们可以来做一下错误示范 这个是我们的Hello java文件 打开命令提示符 编译HelloWorld java 首先这肯定不是环境变量搞错了 可是我文件明明在目录下面 怎么就找不到文
  • Pandas50个高级高频操作

    01 复杂查询 实际业务需求往往需要按照一定的条件甚至复杂的组合条件来查询数据 接下来为大家介绍如何发挥Pandas数据筛选的无限可能 随心所欲地取用数据 1 逻辑运算 Q1成绩大于36df Q1 gt 36 Q1成绩不小于60分 并且是C
  • 构造函数&类属性和实例属性&析构函数

    1 构造函数 概念 构造函数包括 new 和 init 构造函数 也被称为构造器 指的是当创建对象的时候 被自动调用的函数 注意 在Python中 以 xxx 方式命名的函数被称为魔术函数 魔术方法 这类函数在使用的时候无需手动调用 在进行