Python400

面向对象基础

python对象包含三个部分:

  1. id
  2. type
  3. value
    1. 属性
    2. 方法

新建一个类对象 先init再new

构造函数 _ _ i n i t _ _ ( ) \_ \_ init \_\_ () __init__()

用于执行实力对象的初始化工作, 对象创建后初始化当前对象的相关属性, 无返回值;

通常用故意初始化实例对象的实例属性,

通过类名(参数列表)来调用构造函数,将创建好的对象返回给相应的变量

实例属性

从属于实例对象的属性(也可以叫实例变量)

一般在 _ _ i n i t _ _ ( ) \_ \_ init \_\_ () __init__()方法中通过

​ self.实例属性名 = 初始值

在类中的其他的实例方法中也可以通过self.实例属性名来调用

class Student:#模具
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def say_score(self):
        print("{0}的年龄是:{1}".format(self.name, self.age))
s1 = Student("Wong",22)
s1.say_score()
s1.salary = 10000 ## 此时s1对象中多了一个salary属性
s2 = Student("xxx",20) ##s2中并没有salary属性,因为模具中无

实例方法

实例对象调用方法的本质:

实例对象 a = Student(), a.say_score()?

有type类型的模具来创造Student类,里面存放了常量,代码之类的

先创建Student类(有属性和方法了),堆中有地址(🎂)了,self代表的是对象本身,赋给栈中的变量a, a在调用say_score方法的时候,需要传一个self给say_score,传的就是这个🎂地址 Student.say_score(a)中a的地址也是🎂, 实际上解释器就是这么调用的

类对象

如果 ss = Student, 就指向了同样的类对象

工厂模式

单例模式

class mysingleton:
    __obj = None
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls) ##然后把建好的对象放在了__obj这个类属性里面
    	return cls.__obj
    def __init__(self,name):
        print("init...")
        self.name = name

现在创建对象:

a = mysingleton('aa')
b = mysingleton('bb')

图略

地址是一个,但初始化方法调了两次, 如果是单例的话,应该只有一个对象

class mysingleton:
    __obj = None
    #这里加入一个_init_flag作为是否已经执行初始化的标志
    __init_flag = True
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls) ##然后把建好的对象放在了__obj这个类属性里面
    	return cls.__obj
    def __init__(self,name):
        if self.__init_flag:
        	print("init...")
        	self.name = name
            self.__init_flag = False##如果执行到这里,直接改掉了类属性, 执行一次init方法后,__init_flag就变为False了, 不会再到第10行及以后了
#类里面写东西千万不能丢掉self.xxx这个, 如果line 13那个位置不加self就会改不过来__init_flag为False  
a = mysingleton('aa')
b = mysingleton('bb')
print(a)
print(b)
#他们的name都是aa,地址也都是一个地址, line15执行过一次初始化了, line16不再执行'init'也只会print一次

工厂模式改单例模式

class carfactory:
    __obj = None
    __init_flag = True
    
    def create_car(self,brand):
        '''这里不能写self.brand
        因为self.brand就是类属性了,这里的brand是实例属性'''
        if brand == 'BMW':
            return bmw()
        elif brand == 'Benz':
            return benz()
        elif brand == 'BYD':
            return byd()
        else:
            return '其他品牌'
    
    def __new__(cls, *args, **kwargs):
        if cls.__obj == None:
            cls.__obj = object.__new__(cls) 
    	return cls.__obj
    
    def __init__(self):
        if self.__init_flag:
        	print("init CarFactory...")
            self.__init_flag = False
 
class benz:
    pass
class byd:
    pass
class bmw:
    pass

文件和IO流

图略

创建文件对象open()

open用于创建文件对象, 基本语法如下

open(文件名[,打开方式])

打开方式如下:

模式描述
r
w写:如果文件不存在则创建;存在则重写新内容
a追加append模式:如果文件不存在则创建;存在则在文件末尾追加内容
b二进制模式,可与其他模式组合使用
+读写模式,可与其他模式组合使用

例如f = open(r"d:\test.txt","w"), r是为了不care转义字符

没有增加'b'模式则默认创建文本文件对象, 处理的对象基本单元是字符;如果是二进制模式'b', 创建的是二进制文件对象, 处理的基本单元是字节.例如f = open(r"d:\test.jpg","b")

文本文件的写入

三个步骤:

  1. 创建文件对象
  2. 写入数据
  3. 关闭文件对象
f = open('a.txt','a')
s = "随便写写 \n 随便写写"
f.write(s)
f.close()

执行py程序需要通过解释器 ⇒ \Rarr 解释器调用操作系统的资源(程序), ⇒ \Rarr 操作系统要操作硬盘文件. 要记得关闭否则会浪费硬盘资源

编码知识

图略

解释器执行程序会调用操作系统(py解释器编码unicode)生成一个文件,编码是操作系统(Windows)的默认编码格式gbk. 在这个过程中会把unicode转化成gbk, 再次打开时应该使用gbk.

写入数据

write(a): 把字符串a写入到文件中
writelines(b): 把字符串列表写入文件中, 要自己加入换行符

f = open(r"b.txt",'w', encoding='utf-8')
s = ["随便写写\n","第二行\n","第三行\n"]
f.writelines(s)
f.close()

close()关闭文件流

结合异常机制, 如果中途程序崩溃, 要走完全部程序流程最后关闭硬盘文件.

try:#放操作
    f = open(r"my01.txt","a")
    str = "WongYiichun"
    f.write(str)
#异常,一旦上面的出问题了,就到下面这部分excpet来执行
except BaseExecption as e:##e是引用名称
    print(e)
finally:##必须执行
    f.close()

以上述代码为例, 对象f中有一个缓冲区, 调用write(str)时会把字符串先写到缓冲区, 真实的硬盘上该文件中没有这个str的, 调用flush()时,数据会’冲入’文件中(准确地说,是真正写到文件中).

调用close()方法时 ⇒ \Rarr 操作系统会将缓冲区的数据写入文件 ⇒ \Rarr 再关闭文件, 释放对象及释放资源

with语句(上下文管理器)

相当于在with前加了一个还原点, 进with之前啥子样, 结束with代码块时就啥子样.

s = ["随便写写\n","第二行\n","第三行\n"]
with open(r"b.txt",'w', encoding='utf-8') as f:
	f.writelines(s)

文本文件的读取

read([size]): 从文件中读取size个字符串(一个字母一个汉字都是一个字符==?==), 并作为结果返回,;如果没有size参数, 则读取整个文件,读取到文件末尾,会返回空字符串

readline(): 读取一行内容作为结果并返回;读取到文件末尾, 会返回空字符串

readlines(): 文本文件中, 每一行作为一个字符串存在列表中, 返回该列表

##读取文本文件
with open(r"b.txt","r",encoding = "utf-8")as f:
    str = f.read()
    print(str)

只读一个字符

with open(r"b.txt","r",encoding = "utf-8")as f:
   k = f.read(1)
   print(k)

文件较小时一次性读取全部

with open(r"b.txt","r",encoding = "utf-8")as f:
    print(f.read(1))

按行读取一个文件

with open(r"b.txt","r",encoding = "utf-8")as f:
    while True:
        fragment = f.readline()
        if not fragment:##不为空
            break
         else:
            print(fragment, end = ",")

使用迭代器(每次返回一行)读取文本文件

with open(r"b.txt","r",encoding = "utf-8")as f:
    for a in f:
        print(a,end=",")

enumerate()函数和推导式

with open('e.txt','r',encoding = 'utf-8') as f:
    lines = f.readlines()
    lines = [line.rstrip() +'#'+str(index) for index,line in enumerate(lines)]##函数推导式,rstrip()方法用于去空格
with open('e.txt','w',encoding = 'utf-8') as f:
    f.writelines(lines)

文件拷贝

with open('io_file.png','rb') as f:
    with open('io_copy.png','wb') as w:
    	for line in f.readlines():
        	w.write(line)

print('图片拷贝完成')

文件对象的常用属性和方法

文件对象的属性

属性说明
name返回文件的名字
mode返回文件的打开模式
closed若文件已被关闭则返回True(Indicator)

文件对象的打开模式, 此处不再赘述

文件对象的方法 []内的内容表示可选

方法名说明
read([size])从文件中读取size个字符或字节的内容并返回; 若省略参数,则读取全部内容
readline()从文本文件中读取一行内容
readlines()把文本文件中的每一行都作为独立的字符串对象, 将这些对象放入列表并返回
write(str)将字符串str写入文件
writelines(s)将字符串列表s写入文件, 不添加换行符
seek(offset[,whence])将文件指针移动到新的位置, offset表示相对于whence的位置.off为正向末尾移动,为负向开始那边移动;whence的含义:0从文件头开始计算(默认值); 1:从当前位置开始计算; 2:从文件尾开始计算
tell()返回文件指针的当前位置
truncate([size])不论指针在什么位置, 只留下指针前size个字节的内容,其余全部删除; 若没有传入参数, 则指针当前位置到文件末尾的内容全部删除
flush()把缓冲区的内容写入文件, 但不关闭文件
close()把缓冲区的内容写入文件, 同时关闭文件, 释放文件对象的相关资源

使用pickle序列化

import pickle
with  open(r"xxxx.dat","wb") as f:
    a1 = "Wong"
    a2 = 234
    a3 = [20,30,40]
    pickle.dump(a1,f);pickle.dump(a2,f);pickle.dump(a3,f)
    
with  open(r"xxxx.dat","wb") as f:
    b1 = pickle.load(f)
    b2 = pickle.load(f)
    b3 = pickle.load(f)
    print(b1); print(b2); print(b3)
   
id(a1)##不是一个对象
id(b1)

CSV文件的读取和写入

读取:

import csv
with open("iris.csv","r") as f:
    a = csv.reader(f)
    #print(list(a)) return一个大列表
    ##如果执行完print(list(a))后,文件指针已经在文件末尾了, 下一个就print出来就没东西了
    for row in a:
        print(row)

写入: 一行就是一个列表

c = [[1002,"Q",6],[1003,"W",7]]
with open("ee.csv","w") as f:
    b = csv.writer(f)
    #但似乎写入的时候每次都会换行,中间会空一行
    b.writerow(["id","姓名", "年龄"])
    b.writerow(["1001","Wong","18"])
    b.writerows(c)#写入一个列表

OS模块

os.path模块

帮助我们对操作系统的进行操作

import os
os.system("notepad.exe")
os.system("regedit")#注册表
os.system("ping www.baidu.com")#出现乱码的话在pycharm里面的settings可以查encoding改为gbk
os.startfile(r"D:\Changyong\WeChat\WeChat.exe")##调用微信等可执行程序

文件和目录操作

os模块下常用的操作文件的方法

方法名描述
remove(path)删除指定的文件
rename(src, dest)重命名文件或目录
stat(path)返回文件的所有属性
listdir(path)返回path目录下的文件和目录列表

os模块下常用的操作目录的方法

方法名描述
mkdir(path)创建目录
makedirs(path1/path2/…)创建多级目录
rmdir(path)删除目录
removedirs(path1/path2/…)删除多级目录
getcwd()return当前工作目录
chdir(path)把path设为工作目录
walk()遍历目录树
sep当前操作系统使用的路径分隔符

os.path

图略

walk()遍历

#coding = utf-8
import os
allfiles = []
path = os.getcwd()
list_files = os.walk(path)
for dirpath,dirnames,filenames in list_files:
    for dir in dirnames:
		allfiles.append(os.path.join(dirpath,dir))
	for file in filenames:
		allfiles.append(os.path.join(dirpath,file))

for file in allfiles:print(file)

shutil拷贝和压缩

拷贝
import shutil
shutil.copy("a.txt","a_copy.txt")
shutil.copytree("iris-data","testcopy")#注意不要和已有目录冲突
#参数ignore, 执行拷贝操作时不copy哪些文件
shutil.copytree("iris-data","testcopy",ignore = ignore_patterns("*.txt","*.html"))
压缩
shutil.make_archive("压缩包所在位置及名字","压缩格式","压缩文件夹名字")###最后一个参数必须是文件夹
shutil.make_archive("testcopy","zip","iris-data/Iris.csv")
zipfile
import  zipfile
z1 = zipfile.ZipFile("testcopy/a.zip","w")
z1.write("a.txt");z1.write("b.txt")
z1.close()
解压
import  zipfile
z2 = zipfile.ZipFile("testcopy/a.zip","r")
z2.extractall("test")##解压到wd下的叫test的文件夹中
z2.close()

递归算法

递归目录树

#coding = utf-8
import os
allfiles = []
def getallfiles(path,level):
    childdir = os.listdir(path)
     for file in childdir:
         filepath = os.path.join(path,file)
         if os.path.isdir(filepath):
             getallfiles(filepath,level+1)
         allfiles.append("  "*level + filepath)
     return (allfiles)

f = getallfiles('testcopy',0)

for  n in reversed(f):
    print(n)

异常情况

异常的基本结构

try:
    被监控的可能引发异常的语句块
except BaseException as e:
    异常处理语句块
try:
    print("step1")
    a = 3/0
    print("step2")#这个不会执行
except BaseException as e:  #产生异常的类对象
    print("step3")
    print(e)
 
print("step4")

多个except结构

前一个except的异常不能时候一个异常的父类

try:
    可能出现异常的语句块
except exception1:
    处理异常1的语句块
except exception2:
    处理异常2的语句块
except exception3:
    处理异常1的语句块
#...
except BaseException:
    可能出现遗漏的异常的语句块 

try… except…else结构

try:
    a = input("请输入被除数:")
    b = input("除数:")
    c = float(a) / float(b)
except ZeroDivisionError:
    print('The division coud not be zero')
except NameError:
    print("There is no variable named a or b")#例如line3那里b写成了d
except ValueError:
    print("No string here")
except BaseException as e:
    print("e")
else:
    print("结果是:", c)

try… except…finally结构

finally: 无论异常是否发生, finally块都会执行, 通常用来释放try块中申请的资源

try:
    a = input("请输入被除数:")
    b = input("除数:")
    c = float(a) / float(b)
except ZeroDivisionError:
    print('The division coud not be zero')
except NameError:
    print("There is no variable named a or b")#例如line3那里b写成了d
except ValueError:
    print("No string here")
except BaseException as e:
    print("e")
else:
    print("结果是:", c)
finally:
    print("无论是否发生异常我都会执行")
 
print("执行完毕")

在io流, 文件处理中的应用

try:
    f = open("a.txt","r")
    content = f.readline()#只读取一行内容
    print(content)
except:
	print("文件未找到")
finally:
	f.close()  

更严谨一点的话:

try:
    f = open("a.txt","r")
    content = f.readline()#只读取一行内容
    print(content)
except:
	print("文件未找到")
finally:
    try:
	    f.close()  
    except BasicException as e:
        print(e)

 print("结束")

常见异常的解决

因为return可以用作结束方法运行的一种方式, 但return要放在方法末尾, 不要放在try或者except这类语句块的里面.(记住即可)

异常错误
SyntaxError语法错误
NameError尝试访问一个没有声明的变量
ZeroDivisionError零除错误
ValueError数值错误
TypeError类型错误, 例如加号两边必须是数或者必须都是字符串
AttributeError访问对象的不存在的属性
IndexError索引越界异常, 例如列表长度是4, index为5就错了
KeyError字典的Key不存在
异常名称说明
ArithmeticError所有数值计算错误的基类
AssertionError断言语句失败
AttributeError对象没有这个属性
BaseException所有异常的基类
DeprecationWarning关于被弃用的特征的警告
EnvironmentError操作系统错误的基类
EOFError没有内建输入,到达 EOF 标记
Exception常规错误的基类
FloatingPointError浮点计算错误
FutureWarning关于构造将来语义会有改变的警告
GeneratorExit生成器(generator)发生异常来通知退出
ImportError导入模块/对象失败
IndentationError缩进错误
IndexError序列中没有此索引(index)
IOError输入/输出操作失败
KeyboardInterrupt用户中断执行(通常是输入^C)
KeyError映射中没有这个键
LookupError无效数据查询的基类
MemoryError内存溢出错误(对于 Python 解释器不是致命的)
NameError未声明/初始化对象 (没有属性)
NotImplementedError尚未实现的方法
OSError操作系统错误
OverflowError数值运算超出最大限制
OverflowWarning旧的关于自动提升为长整型(long)的警告
ReferenceError弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError一般的运行时错误
RuntimeWarning可疑的运行时行为(runtime behavior)的警告
StandardError所有的内建标准异常的基类 StopIteration 迭代器没有更多的值
SyntaxErrorPython 语法错误
SyntaxWarning可疑的语法的警告
SystemError一般的解释器系统错误
SystemExit解释器请求退出
TabError Tab和空格混用
TypeError对类型无效的操作
UnboundLocalError访问未初始化的本地变量
UnicodeDecodeError Unicode解码时的错误
UnicodeEncodeError Unicode编码时错误
UnicodeError Unicode相关的错误
UnicodeTranslateError Unicode转换时错误
UserWarning用户代码生成的警告
ValueError传入无效的参数
Warning警告的基类
WindowsError系统调用失败
ZeroDivisionError除(或取模)零 (所有数据类型)

with上下文管理

前面讲过了

traceback模块 , 异常写入日志文件

import traceback
try:
    print("Step1")
    num = 1/0
except:
    with open("a.txt","a") as f:
        traceback.print(file = f)
        ##将异常情况写入到a.txt中, 大量异常不建议全部输出到控制台

自定义异常

例如定义一个年龄异常:

此处的一个小问题, 我的电脑似乎是GBK去编码, 但是python默认的是utf8编码,所以此处还是在代码起始位置加上一个说明:# -*- coding: GBK -*,此处参考CSDN中Rachel_nana的博文 .

# -*- coding: GBK -*
class AgeError(Exception):  # 继承Exception类
    def __init__(self, errorInfo):
        Exception.__init__(self)  # 重写init方法
        self.errorInfo = errorInfo

    def __str__(self):
        return str(self.errorInfo) + ",年龄错误, 超出阈值"


if __name__ == "__main__":  # 如果为True, 则模块作为独立文件运行, 可以执行测试代码
    age = int(input("请输入年龄"))
    if age < 1 or age > 150:
        raise AgeError(age)
    else:
        print("你输入的年龄是:", age)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值