> 技术文档 > DAY9-关于我从C++残党转生成Python新兵这件事

DAY9-关于我从C++残党转生成Python新兵这件事

文章参考052-类方法-01-基本语法_哔哩哔哩_bilibili

主语言C++转Python中,面向对象篇(100%)

1.类方法与静态方法

1.类方法

@classmethoddef 类方法名(cls): pass

@classmethod标识,第一个参数是cls(习惯上用cls)

由哪一个类调用的方法,cls就是哪一个类的引用,与self类似 

调用通过类名.类方法,不需要传递cls参数

在类方法内部,cls.可以访问类的属性和调用其他的类方法、

2.静态方法

在一个类中封装一个方法,不需要访问实例属性和调用实例方法,或者不需要访问类属性和调用类方法,这个时候可以把方法封装成一个静态方法

@staticmethoddef 静态方法(): pass

 用@staticmethod标识

调用通过类名.静态方法,不需要创建对象

3.区别

类属性

定义在类内部但在方法外部

所有实例共享同一个类属性

通过类名或实例名都可以访问

修改类属性会影响所有实例

实例属性

定义在方法内部(通常是 __init__ 方法)

每个实例拥有自己的独立副本

只能通过实例名访问

修改一个实例的属性不会影响其他实例

class Dog: # 类属性 species = \"Canis familiaris\" def __init__(self, name, age): # 实例属性 self.name = name self.age = age# 访问类属性print(Dog.species) # 输出: Canis familiaris# 创建实例buddy = Dog(\"Buddy\", 5)miles = Dog(\"Miles\", 3)# 通过实例访问类属性print(buddy.species) # 输出: Canis familiaris# 修改实例属性buddy.age = 6print(buddy.age) # 6print(miles.age) # 3 (不受影响)# 修改类属性Dog.species = \"Canis lupus\"print(buddy.species) # 输出: Canis lupusprint(miles.species) # 输出: Canis lupus (所有实例都受影响)
方法类型 装饰器 第一个参数 访问权限 用途 实例方法 无 self 可以访问和修改实例属性和类属性 操作实例数据 类方法 @classmethod cls 只能访问和修改类属性 工厂方法、操作类级别数据 静态方法 @staticmethod 无 不能访问实例或类属性 与类相关但不依赖实例或类状态的工具函数

可以根据访问权限的需要来确定方法类型 

class MyClass: class_attr = \"类属性\" def __init__(self, value): self.instance_attr = value # 实例方法 def instance_method(self): print(f\"实例方法访问实例属性: {self.instance_attr}\") print(f\"实例方法访问类属性: {self.class_attr}\") # 类方法 @classmethod def class_method(cls): print(f\"类方法访问类属性: {cls.class_attr}\") # print(cls.instance_attr) # 错误,无法访问实例属性 # 静态方法 @staticmethod def static_method(): print(\"静态方法不能访问实例或类属性\") # 但可以访问传入的参数# 使用实例方法obj = MyClass(\"实例值\")obj.instance_method()# 使用类方法MyClass.class_method() # 通过类调用obj.class_method() # 也可以通过实例调用# 使用静态方法MyClass.static_method() # 通过类调用obj.static_method() # 也可以通过实例调用

 2.单例设计模式

目的是让类创建的对象,在系统中只有唯一一个实例

__new__()方法

__new__是object内部的静态方法

在用类名()创建对象时,解释器会做两件事,初始化和分配空间,初始化由__init__(self)实现,而分配空间则由__new__(cls)实现

__new__():为对象分配空间返回对象的引用

解释器获得对象的引用后将其作为第一个参数,传递给__init__()

重写__new__()是固定的,重写改方法一定要用return super().__new__(cls)

注意__new__()是一个静态方法,调用时需要主动传递cls参数

单例功能实现

定义一个类属性,类属性初始值为None,当第一次调用创建对象方法时,在类属性中记录第一个对象的引用,当再次调用创建对象方法时,直接返回第一个对象的引用即可

代码实现:

3.异常

抛出异常:遇到错误停止程序

捕获异常

try: 尝试执行的代码except: 出现错误的处理

捕获错误类型

try: 尝试运行的代码except 错误类型1: 针对类型1,对应处理except(错误类型2,错误类型3): 针对类型2和3,对应处理except Except as result: print(\"未知错误 %s\" % result) 

错误类型根据控制台的输出粘贴进去

最后一个except是用来捕获未知错误的,代码固定

完整语法

try: #尝试运行的代码 passexcept 错误类型1: #针对类型1,对应处理 passexcept(错误类型2,错误类型3): #针对类型2和3,对应处理 passexcept Except as result: #未知错误 print(\"未知错误 %s\" % result)else: #没有异常才会执行的代码 passfinally: #无论有无异常都会执行的代码 print(\"无论有无异常都会执行的代码\")

异常的传递

当函数或者方法出现异常,不会停止,会将异常传递给函数/方法调用的一方

当异常传递到主程序,仍没有异常处理,才会被终止

根据这一特性,只需要在主程序中加入异常捕获即可

抛出异常

创建一个exception对象

用raise关键字抛出异常对象

4.模块

每一个文件都是可以被导入的

导入

import 模块名1,模块名2
import 模块名1import 模块名2
import 模块名1 as 模块别名

 模块别名符合大驼峰命名法

这些导入方法的调用需要:模块名.根据名

这种方法是一次性导入全部工具

局部导入

from 模块名1 import 工具名1

这种导入不需要通过模块名.使用,可以直接使用工具

这种方法是导入部分工具

from 模块名 import * 可实现全部导入

如果两个不同模块中导入相同函数,后面一个会覆盖掉前一个,可以通过别名解决

__name__属性

测试运行模块的代码,只在测试下运行,被导入不会运行

__name__是Python的内置属性,记录着一个字符串

如果是被其他文件导入的,__name__就是模块名

如果是当前执行的程序,__name__就是__main__

按此格式写就可以实现,当前能测试但是导入不会执行的效果

def main(): passif __name__=\"__main__\": main() 

5.包 

包是包含多个模块的特殊目录

目录下有一个特殊文件__init__.py

使用import 包名 可以一次性导入所有模块

from . import 模块名,从当前目录导入模块 ,通常写在__init__.py里面

使用pip安装/卸载第三方模块

例如pygame是一个非常成熟的游戏开发模块

一般使用pip install/uninstall 模块名,其他的可以参考别的教材或者问AI。。

6.文件

固定套路:打开,读写,关闭

#open的第一个参数是文件名,区分大小写#文件存在,返回文件操作对象,若不存在,抛出异常file=open(\"文件名\")#read可以一次性读入并返回文件的所有内容text=file.read()print(text)#close负责关闭文件file.close()

 方法执行后,会把文件指针移动到文件末尾

文件指针会告诉read从哪里开始读,第一次打开是在开头,使用read后会移动到文件末尾

打开

f=open(\"文件名\",\"访问方式\")

访问方式:

读取与写入

read一次性读取所有内容

readline可以一次性读取一行内容 ,执行后,指针会移动到下一行

 无限循环+readline逐步读取

while True: text=readline() if not text: break print(text)

写入

文件名.write(要写入的文本) 

ASCII编码表与UNICODE编码

ASCII编码共256个针对英文,用一个字节描述

UNICODE中的UTF-8用1-6个字节来描述,汉字3个字节,涵盖范围几乎所有地球文字

eval()函数

不要滥用eval,不要用eval直接转换input的结果