课程笔记--006(IO操作、模块) 20200320

IO编程及模块

  • 一、IO编程
    • 文件读写
      • 打开文件
      • 读文件
      • 写文件
      • with 语句
      • 注:
  • 二、模块
    • 模块的分类
      • 系统模块(Python官方提供的、内置的模块)
      • 第三方模块
      • 自定义的模块
    • 模块的导入
    • 查看模块
    • 内置模块
      • os模块
      • sys模块
      • time & datetime 模块
      • random模块
      • math模块
    • 模块的定义

一、IO编程

IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。
比如你打开浏览器,访问新浪首页,浏览器这个程序就需要通过网络IO获取新浪的网页。浏览器首先会发送数据给新浪服务器,告诉它我想要首页的HTML,这个动作是往外发数据,叫Output,随后新浪服务器把网页发过来,这个动作是从外面接收数据,叫Input。所以,通常,程序完成IO操作会有Input和Output两个数据流。当然也有只用一个的情况,比如,从磁盘读取文件到内存,就只有Input操作,反过来,把数据写到磁盘文件里,就只是一个Output操作。

文件读写

读写文件是最常见的IO操作。Python内置了读写文件的函数,用法和C是兼容的。

读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。

文件操作必不可少的是open函数:对文件读写之前,需要先打开文件,获取文件句柄

注意:open() file() 尽量使用open(),Python3以后不支持file()了

打开文件

要以读文件的模式打开一个文件对象,使用Python内置的open() 函数,传入文件名和标示符:

 open(file_name[,access_mode][,buffering][,encoding=None][,errors=None][,newline=None][,closefd=True][,opener=None])
file_name:一个包含了你要访问的文件路径及文件名称的字符串值。尽量使用绝对路径
access_mode:打开文件的方式:这个参数是非强制的,默认文件访问模式为只读(r)

    操作    说明
    r       以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
    w       以写方式打开,
    a       以追加模式打开 (从 EOF 开始, 必要时创建新文件)
    r+      以读写模式打开
    w+      以读写模式打开 (参见 w )
    a+      以读写模式打开 (参见 a )
    rb      以二进制读模式打开
    wb      以二进制写模式打开 (参见 w )
    ab      以二进制追加模式打开 (参见 a )
    rb+     以二进制读写模式打开 (参见 r+ )
    wb+     以二进制读写模式打开 (参见 w+ )
    ab+     以二进制读写模式打开 (参见 a+ )
fp=open('D:\\TEACH\\Graduate\\PYTHON\\SUESPRG\\test.txt', 'r')

该语句表示返回的File_object是一个指向文件的指针(一个文件对象)文件句柄。比如:

fp=open('D:\\TEACH\\Graduate\\PYTHON\\SUESPRG\\test.txt', 'r')
通过open获取到的文件句柄可以对文件作的操作
    (1)fp.closed
        判断文件是否已经关闭。返回true如果文件已被关闭,否则返回false
    (2)fp.mode
        输出读写模式。返回被打开文件的访问模式。
    (3)fp.name:
        返回文件的名称。
    (4) fp.softspace
        如果用print输出后,是否跟一个空格符,false不打印,true则打印。
    (5)fp.close()
        刷新缓冲区里任何还没写入的信息,并关闭该文件,这之后便不能再进行写入。
    (6)flush()
        把缓冲区中的内容持久化写到磁盘里
        缓存区写满的情况,系统会自动调用flush()方法。
    (7)next()
        把一个file用for...in file这样的循环遍历语句时,就是调用next()函数来实现。

读文件

如果文件打开成功,接下来,调用read() 方法可以一次读取文件的全部内容,Python把内容读到内存,用一个str 对象表示:

s=f.read()

写文件

f.write(s)

test文件内容为:

Hello,Word!
123
2343
fr = open('D:\\test.txt', 'r')
fw = open('D:\\testw.txt', 'w')
s=fr.read()     #'Hello, world!'
print(s)
fw.write(s)
fr.close()
fw.close()
fw = open('D:\\testw.txt', 'a')
x,y=3,-4
z=[1,4,7,-9]
s='\n'+str(x)+'\n'+str(y)++'\n'+str(z)
fw.write(s)
fw.close()

with 语句

但是每次都这么写实在太繁琐,所以,Python引入了with 语句来自动帮我们调用close() 方法:

with open('D:\\test.txt', 'r') as f:
    print(f.read())

这和前面的try … finally 是一样的,但是代码更佳简洁,并且不必调用f.close() 方法。

注:

调用read() 会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见。

  • 可以反复调用read(size) 方法,每次最多读取size个字节的内容。

  • 调用readline() 可以每次读取一行内容,

  • 调用readlines() 一次读取所有内容并按行返回list 。 因此,要根据需要决定怎么调用。

  • 如果文件很小, read() 一次性读取最方便;如果不能确定文件大小,反复调用read(size) 比较保险;

  • 如果是配置文件,调用readlines() 最方便:

#打开txt文件
def openfile(fileename):
    data=[]
    with open(fileename, 'r',encoding='utf-8') as f:
        alllines=f.readlines()
        for line in alllines:
            line.strip()
            temp=line.split('\t')
            tempL=[]
            for j in range(len(temp)):
                if j==0:
                    tempL.append(int(temp[j]))
                else:
                    tempL.append(float(temp[j]))
            data.append(tempL)
    return data

if __name__=='__main__':
    dirr='D:\\TEACH\\Graduate\\PYTHON\\SUESPRG\\'
    filee='Sample1.txt'
    fileename=dirr+filee
    data=openfile(fileename)
    print(data[0:3])
if __name__=='__main__':
    dirr='D:\\TEACH\\Graduate\\PYTHON\\SUESPRG\\'
    filee='Sample3.data'
    fileename=dirr+filee
    OrigCatL,OrigNumL=openfile(fileename)
    print(OrigCatL[0:5])
    print(OrigNumL[0:5])
# 读取data文件
def openfile(fileename):
    with open(fileename,mode = "r",encoding='utf-8') as fr:
        arrayOLines = fr.readlines()
        OrigCatL = []
        OrigNumL=[]
        for line in arrayOLines:
            line=line[:-1]
            listFromLine = line.split(",")
            if listFromLine[0] in ['F','I']:#abalone.data
                OrigCatL.append(-1)
            else:
                OrigCatL.append(1)
            temp=[]
            for j in range(1,len(listFromLine)):
                temp.append(float(listFromLine[j]))
            OrigNumL.append(temp)
       
    return OrigCatL,OrigNumL

        
if __name__=='__main__':
    dirr='D:\\TEACH\\Graduate\\PYTHON\\SUESPRG\\'
    filee='Sample3.data'
    fileename=dirr+filee
    OrigCatL,OrigNumL=openfile(fileename)
    print(OrigCatL[0:5])
    print(OrigNumL[0:5])

另外,可以通过OS库,批量读取文件,详情见文章

二、模块

模块的分类

系统模块(Python官方提供的、内置的模块)

特点:已经安装在了系统中,builtins 默认被导入
	|-- random	
	|-- math	
	|-- os
	|-- os.path
	|-- sys
	|-- time
	|-- datetime
	|-- hashlib
	|-- base64

第三方模块

|-- 非官方的,有第三方提供的
特点:必须安装才能使用
requests	# pip install requests

自定义的模块

xxx.py	导入到其他的py文件中使用
project->package->模块

模块的导入

import package
import package as alias # 使用别名
import package.module
from package import module

查看模块

Python本身就内置了很多非常有用的模块,只要安装完毕,这些模块就可以立刻使用。
随着使用python的时间越来越长,安装的python模块也越来越多,想要查看一下安装的python模块,查看方法如下:

一、命令行下使用pydoc命令
在命令行下运行$ pydoc modules即可查看

二、在python交互解释器中使用help()查看
在交互式解释器中输入 help("modules")即可,效果跟在命令行下输入$ pydoc modules是一样的

内置模块

一:os模块,(文件和目录)用于提供系统级别的操作
二:sys模块:用于提供对解释器相关的操作
三:hashlib模块:用于加密相关的操作,代替了md5模块和sha模块,
主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
四:shutil模块:高级的 文件、文件夹、压缩包 处理模块(递归,文件复制等)
五:configparser模块:用于对特定的配置进行操作,
六:logging: 用于便捷记录日志且线程安全的模块
七:time & datetime 模块:时间相关的操作,时间有三种表示方式:
八:random模块:随机数
九:json 和 pickle模块
十:shelve模块:一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

os模块

os模块是与操作系统交互的一个接口,os(operator system)操作系统主要用来操作操作系统中的文件系统,常见的方法:

|-- cpu_count	# 获取当前系统的cpu核数
|-- getcwd	# 表示当前路径,注意,获取的是绝对路径
|-- curdir	# (属性)表示当前路径,注意,相对路径
|-- chdir	# 修改当前工作空间路径
|-- mkdir	# 创建文件夹,注意:只能创建一层
|-- makedirs	# 创建文件夹,可以级联创建多层
|-- chmod	# 修改权限
|-- listdir	# 遍历得到当前工作空间下的所有文件及文件夹,返回一个列表
|-- remove	# 删除文件
|-- removedirs	# 删除文件夹,注意,可以多级删除
|-- rename	# 重命名
|-- renames	# 重命名以及修改文件路径
|-- rmdir	# 删除文件夹,注意,应该只能一级一级删除,文件夹必须为空
|-- scandir	# 遍历得到当前工作空间下的所有文件及文件夹,返回一个迭代器对象
|-- sep		# 返回系统对应的文件分割符
|-- system	# 该方法可以执行该系统对应的所有终端命令

os.path模块,是os的子模块
主要是用来操作文件的,判断文件是否存在、判断是文件还是文件夹等等

|-- abspath	# 显示相对路径的绝对路径
|-- basename	# 一般而言,显示路径对应的文件名称 
|-- exists	# 判断文件或者文件夹是否存在
|-- getsize	# 获取文件的大小, 以字节为单位
|-- isdir	# 判断是否是目录
|-- isfile	# 判断是否是文件
|-- join	# 拼接路径		注意:第一个绝对路径之前的参数将会被忽略
|-- split	# 分割文件路径,返回一个元组为文件的路径和文件名


os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息
os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.environ  获取系统环境变量
os.path.abspath(path)  返回path规范化的绝对路径
os.path.split(path)  将path分割成目录和文件名二元组返回
os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

sys模块

sys模块包括了一组非常实用的服务,内含很多函数方法和变量,用来处理Python运行时配置以及资源,从而可以与前当程序之外的系统环境交互。

import sys
#命令行参数List,第一个元素是程序本身路径
print(sys.argv)
#结果['D:/Pycharm Community/python内置函数/sysTest.py']
#获取Python解释程序的版本信息
print(sys.version)
#结果3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:06:47) [MSC v.1914 32 bit (Intel)]
#最大的Int值
#print(sys.maxint)
#返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值(临时修改,不会保存)
print(sys.path)
#返回操作系统平台名称
print(sys.platform) #win32
#退出程序,正常退出时exit(0)
print(sys.exit(0))

time & datetime 模块

三种时间表示:在Python中,通常有这几种方式来表示时间:

1、时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,回的是float类型。
2、格式化的时间字符串
3、元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
import time
#time.sleep(5)
print("睡眠5s")

#sleep()  #线程推迟自定的时间运行,单位为秒
#clock()
#这个需要注意啦,在不同的系统上含义不同,在unix系统上,它返回的是'进程时间',用秒表示的浮点数(时间戳)
#在windows中,第一次调用,返回的是进程运行的实际时间,而第二次之后的调用是自第一次调用后到现在的运行
#的时间,即两次的时间差
# 返回当前时间的时间戳(以秒计算,从1970年1月1日00:00:00开始到现在的时间差)
t = time.localtime()
print(t) #输出time.struct_time(tm_year=2020, tm_mon=4, tm_mday=20, tm_hour=16, tm_min=53, tm_sec=3, tm_wday=0, tm_yday=111, tm_isdst=0)

year = t.tm_year
month = t.tm_mon
print(year) #2020

# gmtime()方法是将一个时间戳转换为UTC时区(0时区)的struct_time。
#返回utc时间的struc时间对象格式
print(time.gmtime()) # 输出time.struct_time(tm_year=2020, tm_mon=4, tm_mday=20, tm_hour=8, tm_min=53, tm_sec=3, tm_wday=0, tm_yday=111, tm_isdst=0)

#-------将结构化时间转换时间戳
print(time.gmtime(time.time()-9000))
# 输出 time.struct_time(tm_year=2020, tm_mon=4, tm_mday=20, tm_hour=6, tm_min=23, tm_sec=3, tm_wday=0, tm_yday=111, tm_isdst=0)

# -----将结构化时间转换Fomart格式的字符串时间
print(time.mktime(time.localtime()))  # 结果1587372783.0

# --将字符串时间转化结构化时间
print(time.strftime("%Y-%m-%d %X",time.localtime())) #结果 2020-04-20 16:53:03

random模块

import random

random模块:

|-- random()		# 返回一个[0,1)的随机数,伪随机数!
|-- randint(m, n)	# 返回[m,n]之间的随机整数
|-- choice()		# 从一个序列中随机选择元素
|-- randrange()		# random.randrange(x)随机随机产生一个[0,x)之间的整数
#0,1之间时间生成的浮点数  float
print(random.random())

#随机生成传入参数范围内的数字 即 1,2,3
print(random.randint(1, 3))

#随机生成传入参数范围内的数字,range顾头不顾尾
print(random.randrange(1, 3))

#随机选择任意一个数字
print(random.choice([1, '23', [4, 5]]))

#随机选择任意两个数字
print(random.sample([1, '23', [4, 5]], 2))

math模块

该模块存在大量的编程语言中,一般这个模块都是用来操作数学运算

|-- ceil		# 只要数值存在小数位,则向上取整
|-- floor		# 只要数值存在小数位,则向下取整
|-- e			# 自然常数
|-- pi			# 圆周率
|-- fabs		# 求绝对值
|-- fmod		# 求模(求余数) fmod(x, y, /)  x % y
|-- pow			# 求幂次方
|-- sqrt		# 开平方根

模块的定义

举个例子,一个abc.py 的文件就是一个名字叫abc 的模块,一个xyz.py 的文件就是一个名字叫xyz 的模
块。
现在,假设我们的abc 和xyz 这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany ,按照如下目录存放:

mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py

引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在, abc.py 模块的名字就变成了mycompany.abc ,类似的, xyz.py 的模块名变成了mycompany.xyz 。

请注意,每一个包目录下面都会有一个__init__.py 的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。init.py 可以是空文件,也可以有Python代码,因为__init__.py 本身就是一个模块,而它的模块名就是mycompany 。
类似的,可以有多级目录,组成多级层次的包结构。比如如下的目录结构:

mycompany
├─ web
│ ├─ __init__.py
│ ├─ utils.py
│ └─ www.py
├─ __init__.py
├─ abc.py
└─ xyz.py

文件www.py 的模块名就是mycompany.web.www ,两个文件utils.py 的模块名分别是mycompany.utils和mycompany.web.utils 。

自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块。

import math

def Dis_Eucl(x1,x2):#欧氏距离
    x1=list(x1)
    x2=list(x2)
    tempsum=0
    for i in range(len(x1)):
        tempsum=tempsum+(x2[i]-x1[i])*(x2[i]-x1[i])
    tempdis=math.sqrt(tempsum)
    return tempdis


def Dis_Manh(x1,x2):#曼哈顿距离
    x1=list(x1)
    x2=list(x2)
    tempsum=0
    for i in range(len(x1)):
        tempsum=tempsum+abs(x2[i]-x1[i])
    return tempsum


def Dis_Cheb(x1,x2):#切比雪夫距离
    x1=list(x1)
    x2=list(x2)
    tempL=[]
    for i in range(len(x1)):
        tempL.append(abs(x2[i]-x1[i]))
    tempdis=max(tempL)
    return tempdis
import math
def Dis_Cos(x1,x2):#余弦距离
    x1=list(x1)
    x2=list(x2)
    tempsum12=0
    tempsum1=0
    tempsum2=0
    for i in range(len(x1)):
        tempsum12=tempsum12+x2[i]*x1[i]
        tempsum1=tempsum1+x1[i]*x1[i]
        tempsum2=tempsum2+x2[i]*x2[i]
    tempdis=1-tempsum12/(math.sqrt(tempsum1)*math.sqrt(tempsum2))
    return tempdis
import sys
import os
dirr='D:\\TEACH\\Graduate\\PYTHON\\SUESPRG\\PackSample'
sys.path.append(dirr)

def dataLoad():
    Points = [[64, -34], [-25, 12], [22, 11], [90,-12],[24, 34], [25, 32], [34, 43], [45,0]]
    return Points

if __name__=='__main__':
    Points=dataLoad()
def CalDis(Points):
    m=len(Points)
    DisMat=[]
    for i in range(m):
        temp1=Points[i]
        Rowi=[]
        for j in range(m):
            temp2=Points[j]
            tempdis=round(DisFun.Dis_Manh(temp1,temp2),4)
            Rowi.append(tempdis)
        DisMat.append(Rowi)

    return DisMat
    
def SaveR(dirr,filename,StrR):
    os.chdir(dirr)
    if not os.path.exists(dirr+'\\Result\\'): 
        os.mkdir('Result')
    Resultname=dirr+'\\Result\\'+filename
    with open(Resultname,'w') as fw:
        fw.write(StrR)
    return 'OK'

你可能感兴趣的:(高级统计编程课程笔记)