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 (所有实例都受影响)
可以根据访问权限的需要来确定方法类型
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的结果