python类与对象、函数、模块、文件和IO

​​​​

python进阶篇

文件与IO

1.基本文件操作

在使用文件对象时,首先需要通过内置的open()方法创建一个文件对象,然后 通过该对象提供的方法进行一些基本文件操作。

  • 1.创建和打开文件

    • open()

      打开文件并创建文件对象

      file = open(filename, mode, buffering)
      file: 被创建的文件对象
      filename: 要创建或者打开文件的文件名,需要使用单引号或者双引号括起来。待打开的文件在当前位置,不用使用绝对路径,否则使用。
      mode: 可选参数,用于指定文件的打开模式。具体P203页
      buffering: 可选参数,用于指定读写文件的缓冲模式。0,不缓存;1,缓存;大于1,则表示缓冲区大小。默认为缓存模式。

      • 1.file = open(“status.txt”)

        • 打开一个不存在的文件时先创建该文件,否则会抛出异常

          • 解决方案

            在当前目录下创建一个名为“status.txt”文件。
            在调用open()函数时,指定mode的参数为w、w+、 a、a+。这样,当要打开的文件不存在时,就可以创建新的文件了。

      • 2.以二进制的形式打开文件

        使用open()函数不仅可以以文本的形式打开文本文件,而且可以以二进制形式打开非文本文件,如图片、音频、视频等。

        • file = open(“picture.png”, ‘rb’)
      • 3.打开文件时指定编码方式

        open()函数打开文件时,默认采用GBK编码,当打开的不是GBK编码时将抛出异常。

        • file = open(‘notice.txt’, ‘r’, encoding=‘utf-8’)
  • 2.close()

    打开文件后,需要及时关闭,以免对文件造成不必要的破坏。

    • file.close()

      close()方法先刷新缓冲区中没有写入的信息,然后在关闭文件,这样可以将没有写入到文件的内容写入到文件中。在关闭文件后,便不能再进行写入操作了。

  • 3.打开文件时使用with语句,保证文件执行完操作后正常关闭。

    打开文件后,要及时将其关闭。从而实现在处理文件时,无论是否抛出异常,都能保证with语句执行完毕后关闭已经打开的文件。
    基本语法格式:
    with 表达式 as target:
      with语句体

    例子:
    with open(“message.txt”, ‘w’) as file:
      pass # 可以改成其他操作语句

  • 4.写入文件内容

    • file.write(string)

      file为打开的文件对象;string为要写入的字符串。
      调用write()方法向文件中写入内容的前提是, 打开文件时,指定的打开模式为w(可写)或者a(追加),否则抛出异常。

  • 5.读取文件

    • 1.读取指定字符

      • file.read([size])

        file为打开的文件对象;size为可选参数,用于指定要读取的字符个数,如果省略则一次性读取所有内容。
        在调用read()方法读取文件内容的前提是,打开文件时,指定的打开模式为r(只读)或者r+(读写),否则将抛出异常。

        例子:
        with open(“message.txt”, ‘r’) as file:
         string = file.read(9)
         print(string)
        注:使用read(size)方法读取文件时,是从文件的开头读取文件。
        指定位置读取文件,file.seek(offset[,whence])
        file: 表示已经打开的文件对象。
        offset: 用于指定移动的字符个数,其具体位置与whence有关。
        whence: 用于指定从什么位置开始计算。值为0表示从文件头开始计算,值为1表示从当前位置开始计算,值为2表示从文件尾开始计算,默认值为0。
        例子:
        with open(“message.txt”, ‘r’) as file:
         file.seek(14) # 移动文件指针到新的位置
         string = file.read(8) # 读取8个字符
         print(string)
        具体见 P208页

        • read()方法读取文件时,如果文件很大,一次读取全部内容到内存,容易造成内存不足。
    • 2.读取一行

      • file.readline()

        with open(”message,txt“, ‘r’) as file:
        number = 0 # 记录行号
        while True:
         number +=1
         line = file.readline()
         if line == ’ ':
          break
        print(number, line, end = ‘\n’) # 输出一行内容

    • 3.读取全部行

      • file.readlines()

        读取全部行的作用同调用read()方法时不指定size类似,只不过读取全部行时,返回的是一个字符串列表,列表每个元素为文件的一行内容。
        例子:
        with open(”message,txt“, ‘r’) as file:
         message = file.readlines()
         print(message)

        • 如果文件比较大时,采用该方法输出读取的文件内容会很慢,这时可以将列表的内容逐行输出。

          例子:
          with open(”message,txt“, ‘r’) as file:
           messageall = file.readlines()
           for message in messageall:
            print(message)

2.目录操作

在python中,内置了os模块以及其子模块os.path,用于对目录或者文件进行操作。

  • 1.os和os.path模块

    • os.sep:用于获取当前操作系统上的换行符,其他部分参见P211页
  • 2.路径

    • 1.相对路径

      import os
      print(os.getcwd()) # 输出当前目录
      其依赖于当前工作目录

    • 2.绝对路径

      import os
      print(os.path.abspath(r’demo\message.txt’)) # 获取绝对路径
      不依赖于当前工作目录

    • 3.拼接路径

      如果想将两个或者多个路径拼接到一起组成一个新的路径,可以使用os.path模块提供的join()函数实现。
      语法格式:
      os.path.join(‘path1,[,path2[,…]]’)
      路径之间用‘ ,’隔开。
      如果路径中没有一个绝对路径,那么最后拼接出来的将是一个相对路径。
      注:使用os.path.join()函数拼接路径时,并不会检测路径是否真实存在。

      例子:
      import os
      print(os.path.join(“E:\program\Python\Code”, “demo\message.txt”))

      如果存在多个绝对路径,那么以从左到右的顺序最后一次出现为准,并且该路径之前的参数都将被忽略。

      • 两个路径拼接成一个路径时,不要直接使用字符串拼接,而使用os.path.join()函数,这样可以正确的处理不同操作系统的路径分隔符。
  • 3.判断目录是否存在

    • os.path.exists(path)

      其中的path可以采用绝对路径,也可以使用相对路径
      返回值:如果给定的路径存在,返回Ture,否则返回False

  • 4.创建目录

    • 1.创建一级目录

      注:该函数只能创建指定路径中的最后一级路径,如果该路径的上一级不存在,则抛出异常FileNotFoundError。

      • os.mkdir(path, mode = 0o777)

        path: 可以是绝对路径,也可以是相对路径。
        mode: 用于指定数值模式,默认值为0777。该参数在非UNIX系统上无效或者被忽略。
        例子:
        import os
        os.mkdir(“C:\demo”)
        如果路径已经存在,将会抛出FileExistsError异常。
        解决办法:
        import os
        path = ‘C:\demo’
        if not os.path.exists(path):
         os.makedir(path)
         print(“目录创建成功!”)
        else:
         print(“该目录已经存在!”)

    • 2.创建多级目录

      • os.mkdirs(name, mode=0o777)

        import os
        os.makedirs(“C:\demo\test\dir\mr”)
        创建C:\demo\test\dir\mr

  • 5.删除目录

    • 使用rmdir()函数只能删除空的目录

      • os.rmdir(path)

        其中,path为要删除的目录,可以是相对路径,也可以是绝对路径。
        例子:
        import os
        os.rmdir(”C:\demo\test\dir\mr“)

        删除C:\demo\test\dir目录下的mr目录,如果删除的目录不存在将会抛出FileNotFoundError异常。

    • 删除非空目录

      • shutil.rmtree(“C:\demo\test”)

        import shutil
        shutil.rmtree(“C:\demo\test”)

        要删除不为空的”C:\demo\test“目录。

  • 6.遍历目录

    指对 指定目录下 的全部目录(包含子目录)及文件浏览一遍。
    os.walk(top[, topdown][, onerror][, followlinks])
    参数说明:
    top: 用于指定要遍历内容的根目录
    topdown: 可选参数,用于指定遍历的顺序,Ture,表示自上而下遍历(即先遍历根目录);False,表示自下而上遍历(即先遍历最后一级子目录),默认为Ture。
    onerror: 可选参数,用于指定错误处理方式,默认为忽略。
    followlinks: 可选参数,详见P218页
    返回值:返回一个包含三个元素的(dirpath, dirnames, filenames)的元组生成器对象。
    dirpath: 当前遍历的路径,是一个字符串
    dirnames: 当前路径下包含的子目录,是一个列表
    filenames: 当前路径下包含的文件,也是一个列表
    例子:
    import os
    tuples = os.walk(“E:\program\Python\Code\01”)
    for tuple1 in tuples:
     print(tuple,’\n’)

    • os.walk(path)返回(路径,子路径,文件)的元组

3.高级文件操作P219页

  • 1.删除文件

    • os.remove(path)

      import os
      path = “mrsoft.txt”
      if os.path.exists(path):
       os.remove(path)
       print(“文件删除完毕!”)
      else:
       print(“文件不存在!”)

  • 2.重命名文件和目录

    • os.rename(src, dst)

      src: 用于指定重命名的目录和文件
      dst: 用于指定重命名后的目录或者文件
      例子:
      import os
      src = “C:\demo\test\dir\mr\mrsoft.txt” 换为目录“demo”
      dst = “C:\demo\test\dir\mr\mr.txt” 换为目录“test”
      if os.path.exists(src):
       os.rename(src, dst)
       print(“文件重命名完毕!”)
      else:
       print(“文件不存在!”)

  • 3.获取文件基本信息

    在计算机上创建文件后,该文件本身就会包含一些信息。
    stat()函数可以获取最后一次访问时间、最后一次修改时间、文件大小等基本信息。
    object = os.stat(path),该函数的返回值是一个对象,该对象包含以下属性,
    st_mode:保护模式
    st_dev:设备名
    st_ino:索引号
    st_uid:用户名
    st_nlink:硬链接号
    st_gid:组ID
    st_size:文件大小,单位为字节
    st_atime:最后一次访问时间
    st_mtime:最后一次修改时间
    st_ctime:最后一次状态变化时间

函数

函数的定义:
def functionname([parameterlist1,parameterlist2]):
 [’’’ 注释’’’]
 [函数体]

函数体:不知道填写什么,可以用pass替代或者“ … ”替代

1.函数调用

  • functionname([参数])

    • 参数之间用" , "分隔
    • 无参数,不传参

2.参数传递

形参和实参:
(1)形参:
在函数定义 / 创建时,函数名后面括号中的参数为“形式参数”
(2)实参
在调用函数时,函数名后面括号中的参数为"实际参数"

注:
(1)当实参为不可变对象时,进行的是值得传递==>值传递后,改变形参的值,实参的值不变
(2)当实参为可变对象时,进行的是引用传递==>引用传递时,改变形参的值,实参的值也一同变化

P162页

  • 1.位置参数

    • 参数在调用时的数量和位置必须和定义时一样
  • 2.关键字参数

    • 使用形参的名字来确定输入的参数值

      注:通过该方式指定实参时,不再需要与形参的位置完全一致,只要将参数名写正确即可。

  • 3.为参数设置默认值

    调用函数时,如果没有指定某个参数将抛出异常,即在定义函数时,直接指定形式参数的默认值。
    定义函数时,指定默认的形参必须在所有参数的最后,否则将产生语法错误。
    def functionname(…, [parameter1 = defualtvalue1]):
    [函数体]

    注意:定义函数时,为形式参数设置默认值要牢记一点==>默认参数必须指向不可变对象。

    • 查看当前函数的默认参数值,函数名._defaults_,其结果是一个元组

    • 可变对象最好使用None作为默认值,否则会出现意料之外的值,P166,这时还需要进行代码的检查

      def demo(obj=None):
       if obj == None:
        obj = [ ]
       print(“obj的值:”,obj)
       obj.append(1)

  • 4.可变参数

    • 可变参数也称为不定长参数,即传入函数的实际参数可以是0个、1个、两个到任意个。

        1. *parameter
        • 表示接受任意多个实际参数,并将其放到一个元组中

          def functionname(*name):
           print("\n我们喜欢的球员有:")
           for item in name:
            print(item)

          functionname(‘邓肯’, ‘乔丹’)

          • 扩展:使用一个已存在的列表作为函数的可变参数,可以在列表的名称前加“ * ”.

            param = [‘邓肯’, ‘帕克’, ‘詹姆斯’]
            functionname(*param)

        1. **parameter
        • 表示任意多个显式赋值的实际参数,并将其放到一个字典中

          def functionname(**sign):
           print( ) # 输出一个空行
           for key, value in sign.items():
            print("[" + key +"] 的绰号是:" + value)

          functionname(邓肯=‘石佛’, 罗冰逊 =‘海上将军’)

          • 扩展:使用一个已经存在的字典作为函数的可变参数,可以在字典的名字前面加“ ** ”

            dict1 = {‘邓肯’: ‘石佛’, ‘罗宾逊’: ‘海上将军’, ‘吉诺比利’: ‘妖刀’}
            functionname(** dict1)

3.返回值: result = return [value]

4.变量的作用域

  • 1.局部变量

    • 指在函数内部定义并使用的变量
  • 2.全局变量

    • 能够作用于函数内外的变量

    • 两种形式

      • 1.在函数外定义

      • 2.在函数内定义

        • 使用global关键字修饰

          • 可以利用该方法,在函数体内修改全局变量值

5.匿名函数

  • 利用关键字lambda

    • result = lambda[arg1, [,arg2, …,argn]]:expression

      例子:

	  import math
	  r = 10
	  result = lambda r: math.pi *r*r
	  print('半径为', r, '的面积为:',result(r))

模块

  • Python 标准库中的模块,标准模块;
  • 第三方模块;
  • 自己开发的自定义模块。

python中的一个".py"文件就是一个模块。

1.自定义模块

  • 1.创建模块,创建的模块尽量不要与Python自带的标准模块名形同。
  • 2.导入模块
  import modelname [as 别名]
  import test1, test2, ...			# 导入多个模型,使用","分隔,不推荐该方法 
  from 模块名 import member/* 			# 利用dir()查看具体导入了哪些定义(变量、函数或者类等)
- 模块搜索目录

  1、在当前目录(即执行的python脚本文件所在目录)下查找
  2、到PYTHONPATH(环境变量)下的每一个目录中查找
  2、到Python的默认安装目录下查找
  以上各个目录的具体位置保存在标准模块sys的sys.path变量中
  import sys
  print(sys.path) # 输出具体目录
  
  
  我们可以通过以下3种方式添加指定的目录带sys.path中。P193
  1.临时添加
  2.增加.pth文件(推荐)
  3.在PYTHONPATH环境变量中添加

2.python中的包(文件夹)

  • 1.创建包

    (1) 创建一个文件夹(setting)
    (2) 在文件夹中创建一个__init__.py的文件,可以不写任何内容,再导入包是会自动执行。

  • 2.使用包

    (1) import+完整包名+模块名

    import setting.size
    通过这种方式导入的模块后,在使用时需要使用完整的名称。
    例子:
    import seeting.size
    if __name__ =='__main__': #__name__,程序可以检查该变量,以确定它在哪个模块中执行
    	print(‘高度:’,setting.size.width)
    	print('宽度:',setting.size.height)
    

    (2) from+完整包名+import+模块名

    from seeting import size
    if __name__ =='__main__': 
    	print(‘高度:’,size.width)
    	print('宽度:',size.height)
    #无需加包名setting
    

    (3) from+完整包名+模块名+import+定义名:加载指定模块

    # 导入setting包下size模块中的width和height变量
    from seeting.size import width, height (*代替全部定义被加载)
    if __name__ =='__main__': 
    	print(‘高度:’,width)
    	print('宽度:',height)
    

类和对象

1.类

  • 1.类的定义

    class ClassName:
     ‘’‘类的帮助信息’’’
     statement

    设计图也就绪,

  • 2.创建类的实例

    • ClassName(parameterlist)
	  class Geese:
	  '''大雁类'''
	  	pass
		  
	  wildGoose=Geese()
	  print(wildGoose)
  • 3.魔术方法

    • init()

      P178页

	  class Geese:
	  	‘’‘大雁类’‘’
	  	def __init__(self):  
	  	# 其中除了self参数外,还可以自定义一些其他参数,例如:def __init__(self, beak, wing, claw):
	  		print(“大雁类”)
	  
	  wildGoose = Geese()  
  在创建类后,类通常会自动创建一个__init__()方法。
  每当创建一个类的新实列时,Python都会自动执行它。
  __init__()方法必须包含一个self参数,并且必须是第一个参数。
  self参数是一个指向实列本身的引用,用于访问类中的属性和方法。在方法调用时会自动传递实际参数self。

	- Python中默认的方法
  • 4.创建类的成员并访问

类的成员主要由实例方法和数据成员组成,可以通过类的实例进行访问。

(1)创建实例方法并访问

所谓的实例方法(行为)是指在类中定义的函数。同_init_()方法一样,实例方法的第一个参数为self,并且必须包含一个参数self。

	  def functionname(self, parameterList):
	  	block # 方法体
	  
	  实例名.functionname(parameterValue)
	  # 其中的参数个数和类中的实例方法个数一致

(2)创建数据成员并访问
 数据成员是指在类中定义的变量,即属性。
 根据定义的位置又可以分为类属性和实例属性。

	- 类属性

	  类属性是指定义在类中,并且在函数体外的属性。
	  类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。
	  class Geese:
	  	'''大雁类'''
	  	neck = "脖子较长"		# 定义类属性
	  	wing = “振翅频率高”		# 定义类属性
	  	leg = “腿位于身份的中心支点,行走自如”			# 定义类属性
	  	def __init__(self):			# 定义类方法(相当于构造方法)
	  		print("我是大雁类,我具有以下特征")
	  		print("Geese.neck")
	  		print("Geese.wing")
	  		print("Geese.leg")
	  
	  geese = Geese() # 实例化过程中运行

	- 实例属性

	  是指定义在类的方法中的属性,只作用与当前实例中。
	  class Geese:
	  	'''大雁类'''
	  	def __init__(self):			# 定义类方法(相当于构造方法)
	  		neck = "脖子较长"		# 定义实例属性
	  		wing = “振翅频率高”		# 定义实例属性
	  		leg = “腿位于身份的中心支点,行走自如”	# 定义实例属性
	  		print("我是大雁类,我具有以下特征")
	  		print("self.neck")
	  		print("self.wing")
	  		print("self.leg")
	  
	  geese = Geese() # 实例化过程中运行
  • 5.访问权限

Python中并没有对属性和方法的访问权限进行限制.

- (1)尾都有双下划线,__foo__

	- 表示定义特殊方法,一般是系统定义名字,如__init__()

- (2)头一个下划线,_foo

	- 表示protected(保护)类型的成员,只允许类本身和子类进行访问,但是不能使用"from module import *"语句导入

	  class Swan:
	  	‘’‘天鹅类’‘’
	  	_neck_swam='天鹅的脖子很长' 		# 定义私有属性
	    def __init__(self):
	  		print('__init__():'  Swan.__neck_swan)	# 在实例方法中访问私有属性
	  
	  swan = Swam() # 创建Swam类的实例
	  print("直接访问:", swam._neck_swan) #保护属性可以通过实例名访问

		- 可以通过类名和实例名进行访问

- (3)头两个下划线,__foo

	- 表示private(私有)类型的成员,只允许定义该方法的类本身进行访问,而且不能通过类的实例进行访问,但是可以通过"类的实列名.类名__xxx"方式访问

	  class Swan:
	  ’‘天鹅类’‘’
	  __neck_swam='天鹅的脖子很长' 		# 定义私有属性
	  def __init__(self):
	  		print('__init__():'  Swan.__neck_swan)	# 在实例方法中访问私有属性
	  
	  swan = Swam() # 创建Swam类的实例
	  print("加入类名:", swam._Swan__neck_swan) # 私有属性,可以通过"实例名.类名__xxx"方式访问
	  print("直接访问:", swam.__neck_swan) # 私有属性不能通过实例名访问,错误❌

		- 可以 通过类名访问,或者“实例名.类名__xxx”访问,但是不能直接通过“实例名.属性名”方式访问

2.属性

  • (1)创建用于计算的属性

    通过@property(装饰器)将一个方法转化为属性,从而实现用于计算机的属性。
    将方法转换为属性后,可以直接通过方法名来访问,不需要在添加“()”。

  语法格式:
  @property
  def methodname(self):
  	block
  
  例子:
  class Rect:
  	def __init__(self, width, height):
  		self.width = wifth
  		self.height = height
  	@property		# 将方法转化为属性
  	def area(self):
  		return self.width*self.height
  rect = Rect(800,600)
  print(“面积:”,rect.area) # 访问的时候没有添加"()"
  • (2)为属性添加安全保护机制
  class TVshow:
  	def __init__(self, show):
  		self.__show = show
  	@property			# 将方法转化为属性
  	def show(self):
  		return self.__show		# 返回私有属性的值
  tvshow=TVshow("正在播放《战狼2》")	
  print("默认:" tvshow.show)
  
  tvshow.show="正在播放《红海行动》"	 #修改属性的值
  print("默认:" tvshow.show) 		# ❌无法修改

	- 实现只读属性

3.继承

被继承的类称为父类或者基类,新的类称为子类或者派生类。

语法格式:
class ClassName(基类1,基类2,...) # 如果不指定,将适用所有python对象的根类object
		''类的信息'''
		类体
  • 方法重写P186

  • 子类中调用父类的__init__()方法

    • 利用super()函数
	super().__init__() # 调用基类的__init__()方法

你可能感兴趣的:(Python相关)