# python3 file文件方法
#open方法
'''
Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。
open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)。
'''
#上次学习了open的基本格式,这里就不多赘述
#f=open(f'C:\Users\zxy\Desktop\fileTest.txt','r')
#open方法完整的参数列表
#open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
#点击源码可以看到 这些参数都是有默认值的,就是使用时可以不指定
'''
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
opener: 设置自定义开启器,开启器的返回值必须是一个打开的文件描述符。
'''
# file对象的一些常用方法
#close() 每次创建文件对象后,在相关操作完成后,一定要使用close方法
#flush() 刷新缓冲区 直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
# fileno 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。
# f=open(r'C:\Users\zxy\Desktop\fileTest.txt','wb')
# print(f.name) #输出文件名 # C:\Users\zxy\Desktop\fileTest.txt
# print(f.fileno()) #输出文件描述符 3
# f.close()
# read() ,readline(),readlines
#seek()移动文件读取指针到指定位置
f=open(r'C:\Users\zxy\Desktop\fileTest.txt','rb+')
num=f.write(b'0123456789abcd')
print(num) # 14
a1=f.seek(5)
print(a1) #5
a2=f.read(1) #读取一个字节 如果没有移动读取指针,应该输出0才对,说明读取指针移动了5
print(a2) #b'5'
# tell 返回文件当前位置
print(f.tell()) # 6 读取指针到6了
f.close()
# truncate(size) 截断文件 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,
# write ,writelines 写入文件
#python3 错误与异常
# 语法错误
'''
语法错误就是语法格式都不对,一般用ide编写的时候会爆红
'''
#异常
'''
即便 Python 程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。
大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:
'''
#ex:
# print(1/0)
'''
Traceback (most recent call last):
File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 17, in <module>
print(1/0)
ZeroDivisionError: division by zero
'''
# print(4*a)
'''
Traceback (most recent call last):
File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 24, in <module>
print(4*a)
NameError: name 'a' is not defined
'''
# 异常处理
'''
java中使用 try catch
python3中 异常处理使用的是 try except
'''
#ex:
try:
a=1/0
print(a)
except:
print("0不能作为除数")
#0不能作为除数
# try/except....else
'''
try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。
else 子句将在 try 子句没有发生任何异常的时候执行。
'''
try:
a=100/5
print(a) # 20.0
except:
print("0不能作为除数")
else:
print(f"除法结束,结果为{a}") # 除法结束,结果为20.0
try:
a = 100 / 0
print(a)
except:
print("0不能作为除数") #0不能作为除数
else:
print(f"除法结束,结果为{a}")
# try -finally
# 这个就比较好理解了,一定会执行的代码,一般类似于文件操作或者一些涉及到释放资源的操作,都会放在finally里
# 抛出异常
#使用raise抛出异常
# x=10
# if x>5:
# raise Exception('x大于5!')
'''
Traceback (most recent call last):
File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 76, in <module>
raise Exception('x大于5!')
Exception: x大于5!
'''
# 用户自定义异常
'''
你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承
继承的概念 有java基础很容易理解,只不过python中的继承还没有学过 之后会学 这里先不探究
'''
# class myError(Exception):
# def __init__(self,value):
# self.value=value
# def __str__(self):
# return repr(self.value)
# python 断言
'''
语法格式为: assert expression
等价于
if not expression:
raise AssertionError
'''
# import sys
# assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
'''
Traceback (most recent call last):
File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 104, in <module>
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
AssertionError: 该代码只能在 Linux 下执行
'''
assert (1/0),'0不能作为除数'
'''
Traceback (most recent call last):
File "F:\PycharmProjects\pythonStudy\study08\02errorAndExceptionTest.py", line 111, in <module>
assert (1/0),'0不能作为除数'
ZeroDivisionError: division by zero
'''
# python 中的面向对象
# 有过java面向对象的底子,其实对python中的面向对象理解应该不是那么难 记住 python可以多继承
'''
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
方法:类中定义的函数。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
'''
# 类定义
class Myclass:
#基本属性
name=''
age=0
#私有属性
__height=180
def say(self):
print(fr"hello my name is {self.name}")
#类有一个名为 __init__() 的特殊方法(构造方法),该方法在类实例化时会自动调用
#构造方法可以分有参构造和无参构造
def __init__(self,name,age):
self.name=name
self.age=age
# def __int__(self):
# pass
# 这里是错误的 python类只有一个构造函数
#self 代表类的实例,而非类
#类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
def prt(self):
print(self)
print(self.__class__)
# 类对象
x=Myclass('zxy',18) #实例化Myclass这个类
print(x.name,x.age) # 访问类的属性 #zxy 18
x.say()# 类的方法 # hello my name is zxy
x.age=100
print(x.name,x.age) # 访问类的属性 #zxy 100
y=Myclass('test',60)
print(y.name,y.age) # test 60
#这里调用x,y两个实例的prt方法来查看一下区别
x.prt()
#<__main__.Myclass object at 0x0000025E140C3FD0>
#<class '__main__.Myclass'>
print("----")
y.prt()
#<__main__.Myclass object at 0x0000025E140C3F10>
#<class '__main__.Myclass'>
#可见 实例是不同实例,但是同一个类;这里可以类比java中的实例对象和类对象
# print(x.__height) # AttributeError: 'Myclass' object has no attribute '__height' 私有属性无法访问
#python支持多继承
'''
class DerivedClassName(Base1, Base2, Base3):
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
'''
#类属性与方法
'''
属性和方法都可以是私有的 用两个下划线定义 __name
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
'''
# 类的专有方法
'''
__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__truediv__: 除运算
__mod__: 求余运算
__pow__: 乘方
'''
# 运算符重载
#比如我们有个自定义类要相加
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
# def __add__(self, other):
# return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2) # Vector (7, 8)
# 如果注释掉__add__的重写代码,则TypeError: unsupported operand type(s) for +: 'Vector' and 'Vector'
# python 命名空间与作用域
'''
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。
命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。
我们举一个计算机系统中的例子,一个文件夹(目录)中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。
'''
'''
内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
'''
#全局变量
var1=5
def function():
var2=6 #局部变量
def function2():
var3=7 #内嵌的局部变量
'''
作用域
作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
有四种作用域:
L(Local):最内层,包含局部变量,比如一个函数/方法内部。
E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
G(Global):当前脚本的最外层,比如当前模块的全局变量。
B(Built-in): 包含了内建的变量/关键字等。,最后被搜索
规则顺序: L –> E –> G –>gt; B。
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
'''
# global和nonlocal关键字
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num) #1
num = 123
print(num) #123
fun1()
print(num) #123
# nonlocal关键字声明
def outer():
var = 10
def inner():
global var # global关键字声明
var = 100
print(var) #100
inner()
print(var) #10
outer()
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num) #100
inner()
print(num) #100
outer()
'''
简单理解:
全局作用域就是说白了模块(单个 .py 文件中)直接声明的变量。
#子类
'''
# 父类
class Parent:
name=''
age=0
__height=180
def __init__(self,name,age,height):
self.name=name
self.age=age
self.__height=height
def speak(self):
print(f"我是{self.name},是父类。")
import parentClass
class Kid(parentClass.Parent):
grade=''
def __init__(self,name,age,height,grade):
parentClass.Parent.__init__(self,name,age,height)
self.grade=grade
def speak(self):
print(f"我是{self.name},是子类")
x=Kid('子类',18,180,"100分")
x.speak()# 我是子类,是子类
super(Kid,x).speak() # 我是子类,是父类。 调用父类方法(注意 ide是.不出来的)
y=parentClass.Parent('父类',50,190)
y.speak() # 我是父类,是父类。