面向对象编程(二)

文章目录

  • __name__ 属性
  • __doc__属性
  • __bases__属性
  • __module__属性
  • __class__属性
  • __init__()函数
  • __new__()函数
  • __del__()函数

name 属性

在Python的类定义中,name 属性通常不是用来描述类本身的,而是用来描述类实例的。当我们讨论类的属性时,name 通常指的是类实例的 class.name,它表示实例所属的类的名字。

但是,如果你是在类的定义内部使用 name,并且没有显式地定义它,那么 name 将引用当前类的名字。这是因为在类定义内部,name 是一个内置属性,它表示当前类的名字。

下面是一个简单的例子,展示了如何在类定义中使用 name 属性:

class MyClass:def __init__(self):print(f"Instance of {self.__class__.__name__} created.")# 创建 MyClass 的实例
obj = MyClass()# 输出:Instance of MyClass created.

在这个例子中,当创建 MyClass 的实例时,init 方法内的 self.class.name 会输出 “MyClass”,即实例所属的类的名字。

另外,如果你在类的定义外部想要获取类的名字,你可以直接访问类的 name 属性:

class MyClass:passprint(MyClass.__name__)  # 输出:MyClass

这里,MyClass.name 返回的是字符串 “MyClass”,它表示类的名字。

总结一下,name 属性在类定义中有两种常见的用法:

  • 在类定义内部,name 表示当前类的名字。
  • 在类定义外部,MyClass.name 表示类 MyClass 的名字。

在实例方法中,self.class.name 可以用来获取实例所属类的名字。

__doc__属性

在Python中,doc 是一个特殊的属性,用于存储类的文档字符串(docstring)。文档字符串是一个位于类、方法或函数定义开头的字符串,通常用于解释这个类、方法或函数的作用和用法。它可以通过在定义之后直接跟上一个被三引号(‘’’ 或 “”")包围的字符串来设置。

下面是一个简单的例子,展示了如何在类中定义和使用 doc 属性:

class MyClass:"""这是一个示例类的文档字符串。这个类用于演示 __doc__ 属性的用法。"""def __init__(self):pass# 访问类的 __doc__ 属性
print(MyClass.__doc__)

当你运行这段代码时,它会输出类的文档字符串,即:

这是一个示例类的文档字符串。
这个类用于演示 doc 属性的用法。

在类的实例方法中,你也可以通过 self.class.doc 来访问类的文档字符串。

class MyClass:"""这是一个示例类的文档字符串。"""def show_doc(self):print(self.__class__.__doc__)# 创建类的实例并调用方法
obj = MyClass()
obj.show_doc()

这段代码也会输出同样的文档字符串。

doc 属性对于编写文档和提供代码的自我解释非常有用。当你使用像 help() 函数或IDE的自动完成功能时,它们通常会显示这些文档字符串,以帮助开发者理解代码的功能和用法。

请注意,如果你没有为类、方法或函数提供文档字符串,那么 doc 属性的值将是 None。

__bases__属性

在Python中,bases 是一个类的属性,它返回一个包含类所有基类(父类)的元组。这个属性对于理解类的继承层次结构非常有用。如果一个类没有显式地继承任何基类,那么 bases 将返回一个只包含 object 的元组,因为所有的类都隐式地继承自 object 类(在Python 3中)。

下面是一个简单的例子,展示了如何使用 bases 属性:

class BaseClass:passclass DerivedClass(BaseClass):pass# 查看 BaseClass 的基类
print(BaseClass.__bases__)  # 输出:(<class 'object'>,)# 查看 DerivedClass 的基类
print(DerivedClass.__bases__)  # 输出:(<class 'BaseClass'>,)

在这个例子中,BaseClass 没有显式地继承任何类,因此它的 bases 属性返回了包含 object 的元组。DerivedClass 继承自 BaseClass,因此它的 bases 属性返回了包含 BaseClass 的元组。

bases 属性通常用于元类编程和类反射,在这些情况下,你可能需要查看或修改一个类的继承层次结构。然而,在普通的类定义和使用中,你很少需要直接访问这个属性。

请注意,bases 是一个只读属性,你不能直接修改它来改变一个类的继承层次结构。如果你需要改变类的继承关系,你应该通过修改类定义来实现。

__module__属性

在Python中,__module__属性是一个内置的类属性,它表示类定义所在的模块的名字。这个属性通常用于反射和调试,帮助开发者确定类是从哪个模块加载的。

当类是在主程序(即脚本的顶层,不是在一个函数或方法内部)中定义时,__module__属性的值通常是"main",表示这个类是在主模块中定义的。如果类是在一个导入的模块中定义的,那么__module__属性的值将是那个模块的名字。

下面是一个简单的例子,展示了__module__属性的用法:

假设我们有两个Python文件,module_a.py和module_b.py。

module_a.py的内容如下:

class MyClass:pass

module_b.py的内容如下:

import module_adef show_module():print(module_a.MyClass.__module__)show_module()

当我们运行module_b.py时,输出将是:

module_a

这表明MyClass类是在module_a模块中定义的。

如果我们直接在module_a.py中运行以下代码:

print(MyClass.__module__)

输出将会是:

__main__

这表示MyClass是在主模块中定义的,即直接在module_a.py脚本中定义的。

__module__属性在动态加载和实例化类时特别有用,特别是当你需要基于类的名字来查找和加载类时。例如,使用globals()或locals()函数结合__module__属性,你可以获取到定义类的模块的全局变量字典,进而从那里获取类对象。

请注意,__module__属性是由Python解释器自动设置的,通常不需要你手动去修改它。

__class__属性

在Python中,class 是一个实例属性,它指向实例所属的类。对于类对象本身,class 属性则指向其元类(metaclass)。

元类主要用于控制类的创建行为,它们通常用于实现如抽象基类、类装饰器、类属性继承等高级功能。大多数情况下,你不需要直接使用元类,除非你正在进行一些底层的Python编程或框架开发。

对于类实例来说,class 属性允许你查询或修改实例所属的类。然而,通常不建议直接修改实例的 class 属性,因为这可能会导致不可预见的行为和错误。

下面是一个简单的例子,展示了如何使用 class 属性:

class MyClass:pass# 创建一个 MyClass 的实例
obj = MyClass()# 使用 __class__ 属性来查看实例所属的类
print(obj.__class__)  # 输出: <class '__main__.MyClass'># 对于类对象本身,__class__ 指向其元类
print(MyClass.__class__)  # 输出: <class 'type'># 验证 obj 的类确实是 MyClass
print(obj.__class__ is MyClass)  # 输出: True# 尝试修改 obj 的 __class__ 属性(不推荐这样做)
# obj.__class__ = AnotherClass
# 这通常会导致错误或不可预见的行为

在上面的例子中,我们创建了一个名为 MyClass 的类,并创建了一个该类的实例 obj。通过 obj.class,我们可以确认 obj 是 MyClass 的一个实例。同时,通过 MyClass.class,我们可以看到 MyClass 的元类是 type。

记住,虽然 class 属性是可访问的,但在大多数情况下,你应该避免修改它,除非你非常清楚修改它的后果。在Python中,类的继承、实例的方法和属性查找等行为都是基于 class 属性的,因此直接修改它可能会导致程序的行为变得不可预测。

init()函数

在Python中,init() 是一个特殊的方法,被称为类的构造函数或初始化方法。这个方法在创建类的新实例时自动调用,用于初始化实例的属性或执行其他必要的设置。

init() 方法通常接受 self 作为其第一个参数,self 代表类的实例本身。除了 self 之外,init() 还可以接受其他参数,这些参数在创建实例时由用户传递。

下面是一个简单的例子,展示了如何在Python类中使用 init() 方法来初始化实例属性:

class Person:def __init__(self, name, age):# 初始化实例属性self.name = nameself.age = age# 创建Person类的实例
person1 = Person("Alice", 30)# 访问实例属性
print(person1.name)  # 输出: Alice
print(person1.age)   # 输出: 30

在这个例子中,Person 类有一个 init() 方法,它接受两个参数:name 和 age。当创建 Person 类的实例时,这些参数的值被传递给 init() 方法,然后方法将这些值赋给实例的 name 和 age 属性。

init() 方法允许你在创建对象时设置对象的初始状态。这对于确保对象在使用前具有合理的默认状态或根据用户提供的参数进行配置非常有用。

你也可以在 init() 方法中执行其他初始化任务,比如调用其他方法、设置其他属性、进行必要的计算等。

请注意,init() 方法的名称是固定的,包括前后的双下划线。这是Python的约定,用于标识特殊方法。如果你在自己的代码中尝试定义一个不同名称的方法,它不会被视为类的构造函数。

new()函数

在Python中,new() 是一个静态方法,用于创建一个新的实例对象。它通常在创建对象时首先被调用,负责返回新创建的对象实例。new() 的主要作用是控制实例的创建过程,包括分配内存空间等低级操作。

在大多数情况下,你不需要自己定义 new() 方法,因为Python的内置机制会自动为你处理实例的创建。然而,在某些特殊情况下,如实现单例模式、自定义元类(metaclass)或者控制实例的创建过程时,你可能需要重写 new() 方法。

下面是一个简单的例子,展示了如何使用 new() 方法来控制实例的创建:

class Singleton:_instance = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super(Singleton, cls).__new__(cls)return cls._instance# 创建Singleton类的实例
instance1 = Singleton()
instance2 = Singleton()# 检查是否创建了两个不同的实例
print(instance1 is instance2)  # 输出: True

在这个例子中,Singleton 类通过重写 new() 方法实现了单例模式,确保无论多少次尝试创建 Singleton 的实例,都只会返回一个相同的实例。

需要注意的是,new() 方法在调用时会接收类本身(通常命名为 cls)作为第一个参数,而不是实例对象(self)。这是因为 new() 方法在实例创建之前被调用,所以此时还没有实例对象可用。

另外,new() 和 init() 方法经常一起使用来创建和初始化对象。new() 负责创建实例并返回该实例,而 init() 负责初始化该实例的属性。通常情况下,你不需要重写 new(),除非你需要进行一些特殊的实例创建控制。大多数情况下,只需重写 init() 方法就足够了。

del()函数

在Python中,del()是一个特殊的方法,被称为析构函数或删除方法。这个方法在对象的引用计数减少到0时调用,也就是说,当对象不再被引用,且垃圾回收机制准备回收其占用的内存时,del()方法会被自动执行。它允许你在对象被销毁之前执行一些清理操作,如关闭文件、释放网络资源等。

需要注意的是,Python的垃圾回收机制并不保证__del__()方法会在对象被销毁时立即调用。实际上,Python的垃圾回收机制会尽可能地延迟对象的销毁,以优化内存使用。因此,del()方法的行为并不是完全可预测的,通常不推荐在一般的编程中使用这个方法。

下面是一个简单的例子,展示了如何在Python类中使用__del__()方法:

class MyClass:def __init__(self, name):self.name = nameprint(f"Object {self.name} created.")def __del__(self):print(f"Object {self.name} destroyed.")# 创建MyClass的实例
obj = MyClass("example")# 删除obj的引用,触发__del__()方法
del obj# 输出可能如下,但请注意__del__()的调用不是立即的
# Object example created.
# Object example destroyed.

在这个例子中,当obj变量被del语句删除时,del()方法会被调用,输出一条消息表示对象已经被销毁。然而,由于Python的垃圾回收机制,这条消息可能不会立即显示。

通常情况下,如果你需要在对象不再使用时执行一些操作,更好的做法是使用上下文管理器(enter__和__exit__方法)或实现close()方法,而不是依赖__del()方法。这是因为__del__()方法的调用时机是不确定的,而且它不能处理循环引用的情况,这可能导致资源泄露。

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

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

相关文章

2024年3月GESP等级认证C++编程五级真题

2024年3月GESP认证C编程五级真题试卷 题目总数&#xff1a;27 总分数&#xff1a;100 选择题 第 1 题 单选题 唯⼀分解定理描述的内容是 ( ) ? A.任意整数都可以分解为素数的乘积 B.每个合数都可以唯⼀分解为⼀系列素数的乘积 C.两个不同的整数可以分解为相同…

初步接触C++

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习C&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 文章目录 初步区别C语言和C命名空间1.命名空间的定义2.命名空间的使用 C的输入输出缺省参数1.缺省参数…

http协议中缓存Cache-Control详解

Cache-Control 是一个 HTTP/1.1 协议中的头部字段&#xff0c;用于指定请求和响应遵循的缓存机制。通过这个头部&#xff0c;服务器可以告诉客户端响应可以被缓存多长时间&#xff0c;以及在什么条件下可以被缓存和重新使用。以下是一些常见的 Cache-Control 指令&#xff1a; …

机器学习——神经网络简单了解

一、神经网络基本概念 神经网络可以分为生物神经网络和人工神经网络 (1)生物神经网络,指的是生物脑内的神经元、突触等构成的神经网络&#xff0c;可以使生物体产生意识&#xff0c;并协助生物体思考、行动和管理各机体活动。 (2)人工神经网络,是目前热门的深度学习的研究…

计算坤是如何工作的

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:&#x1f649; &#x1f439;今日诗词:&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac…

进程、线程、协程与虚拟线程(进程相关)

进程、线程、协程与虚拟线程 这一次我们从头&#xff0c;从最大的先开始说&#xff0c;我们从进程开始&#xff0c;因为内容比较多&#xff0c;所以我们分为几个不同的文章来介绍。先从进程&#xff0c;再从线程&#xff0c;最后介绍协程与虚拟线程。 简介 我们以一张操作系…

ehters.js:provider

ethers.jsV5.4文档 安装ethers npm install ethers5.4.0// 引入 import { ethers } from ethersProviders /** Provider类* Provider类是对以太坊网络连接的抽象&#xff0c;为标准以太坊节点功能提供简洁、一致的接口。 */ const provider new ethers.providers.Web3Provider…

2024年第16届大广赛新命题发布-爱华仕箱包

2024年3月27日&#xff0c;2024年第16届大广赛发布了新的命题&#xff0c;爱华仕箱包命题&#xff0c;自2017年起&#xff0c;爱华仕箱包已连续8年担任全国大学生广告艺术大赛命题单位。 爱华仕现已实现百货、超市、电商、礼品、投标、海外市场6大零售网络的全覆盖&#xff0c…

已解决redis.clients.jedis.exceptions.JedisNoScriptException异常的正确解决方法,亲测有效!!!

已解决redis.clients.jedis.exceptions.JedisNoScriptException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 报错原因 解决思路 解决方法 总结 博主v&#xff1a;XiaoMing_Java 在使用Redis进行开发时&#xff0c;我们可…

左值引用、右值引用及移动语义

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 左值 概念 可以取到地址的值就是左值&#xff0c;并且一般情况下可以修改&#xff08;const类型左值不可修改&#xff09;。 左值举例&#xff1a; //左值 int a 0; const int b 1; int* p &a; 右值 概念 不能…

【Golang星辰图】决胜Go语言江湖:六大顶尖库的功能解析与实战攻略

赋能Go开发者&#xff1a;探索与掌握六款核心库的功能与应用场景 前言&#xff1a; 在现代软件开发领域中&#xff0c;Go语言因其实现并发特性的简便性、高性能及简洁高效的程序设计体验而受到广大开发者的推崇。本文旨在为Go语言开发者精选并深入剖析六款广泛应用的核心库&a…

三相四线智能电表直接接入式接线图

大家好&#xff0c;今天我们要聊的是三相四线智能电表的直接接入式接线方式。别担心&#xff0c;我会用简单易懂的语言来解释这个看似复杂的主题。 首先&#xff0c;我们得知道什么是三相四线电表。在我们的生活中&#xff0c;电力供应通常分为单相和三相。三相电&#xff0c;就…

vue 下载图片/视频到浏览器

方法1&#xff1a;直接在当前页面打开图片或者视频 window.location.href url;//借用a标签实现同样效果 const link document.createElement(a) link.href url // 文件地址 link.click(); 方法2&#xff1a;新开一个窗口打开图片或视频 window.open(url); 方法3&#xf…

分页-PageHelper原理以及实时分页-键集分页

一.PageHelper原理 1.使用 PageHelper 是国内非常优秀的一款开源 mybatis 分页插件&#xff0c;它支持常用的主流数据库&#xff0c;例如 Oracle、Mysql、MariaDB、SQLite、Hsqldb 等。 PageHelper 的安装很简单&#xff0c;只需要在 pom.xml 中加入以下依赖即可&#xff1a…

网络类型及数据链路层协议

目录 一、网络的分类 二、数据链路层协议 1、MA网络以太网协议 2、P2P网络 3、HDLC ---高级数据链路控制协议 HDLC地址借用 三、PPP协议 1、PPP协议的优点 2、PPP数据帧封装结构 3、PPP会话的搭建 4、LCP建立——链路建立阶段 4.1协商阶段 4.2认证阶段 4.3 PAP---密…

深入聊聊企业数字化转型这个事儿

01 什么是数字化&#xff1f; 聊数字化&#xff0c;就不得不聊聊信息化、智能化。佛性的说&#xff1a;信息化是数字化的前世&#xff0c;智能化是数字化的来生&#xff01;我习惯用一个结构化的图形来表示事物之间的关系&#xff0c;信息化、数字化、智能化的关系如下&#…

尤大大正式官宣推出VitePress 1.0

VitePress 在现代Web开发领域&#xff0c;构建快速、响应式的文档网站是开发者经常面临的任务之一。VitePress应运而生&#xff0c;它结合了Vue.js和Vite的强大功能&#xff0c;为开发者提供了一个简单易用的静态站点生成器。Vue.js作为一种流行的前端框架&#xff0c;以其简洁…

网络安全:Kali Linux 进行SQL注入与XSS漏洞利用

目录 一、实验 1.环境 2.Kali Linux 进行SQL注入 3.Kali Linux 进行XSS漏洞利用 二、问题 1.XSS分类 2.如何修改beef-xss的密码 3.beef-xss 服务如何管理 4.运行beef报错 5.beef 命令的颜色有哪些区别 6.owasp-top-10 有哪些变化 一、实验 1.环境 &#xff08;1&a…

30---SDRAM电路设计

视频链接 SDRAM电路设计01_哔哩哔哩_bilibili SDRAM电路设计 1、SDRAM简介 SDRAM&#xff1a;Synchronous Dynamic Random Access Memory&#xff0c;同步动态随机存储器。 同步是指其时钟频率和CPU前端总线的系统时钟相同&#xff0c;并且内部命令的发送与数据的传输都以…

如何避免SQL注入攻击?

&#x1f413;序言 当涉及到数据库操作时&#xff0c;防止SQL注入攻击至关重要。SQL注入是一种常见的网络安全威胁&#xff0c;攻击者通过在用户输入中插入恶意的SQL代码&#xff0c;从而可以执行未经授权的数据库操作。 &#x1f413;避免方式 使用参数化查询 使用参数化查询…