Python快速入门之基础(三)

这篇主要讲文件和线程。

python文件操作

一、读文件

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

>>> f = open('/Users/michael/test.txt', 'r')

标示符’r’表示读,这样,我们就成功地打开了一个文件。

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

>>> f.read()
'Hello, world!'

最后一步是调用close()方法关闭文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:

>>> f.close()

由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确地关闭文件,我们可以使用try … finally来实现:

try:
    f = open('/path/to/file', 'r')
    print f.read()
finally:
    if f:
        f.close()

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

with open('/path/to/file', 'r') as f:
    print f.read()

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

要读取二进制文件,比如图片、视频等等,用’rb’模式打开文件即可

二、写文件

写文件和读文件是一样的,唯一区别是调用open()函数时,传入标识符’w’或者’wb’表示写文本文件或写二进制文件:

>>> f = open('/Users/michael/test.txt', 'w')
>>> f.write('Hello, world!')
>>> f.close()

但是只有调用close()方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用close()的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用with语句来得保险:

with open('/Users/michael/test.txt', 'w') as f:
    f.write('Hello, world!')

在Python中,文件读写是通过open()函数打开的文件对象完成的。使用with语句操作文件IO是个好习惯。

python文件读写的参数解释如下

w:以写方式打开

a:以追加模式打开 (从 EOF 开始, 必要时创建新文件)

r+:以读写模式打开

w+:以读写模式打开 (参见 w )

a+:以读写模式打开 (参见 a )

rb:以二进制读模式打开

wb:以二进制写模式打开 (参见 w )

ab:以二进制追加模式打开 (参见 a )

rb+:以二进制读写模式打开 (参见 r+ )

wb+:以二进制读写模式打开 (参见 w+ )

ab+:以二进制读写模式打开 (参见 a+ )

另外对于大文件我们还可以分段读写

  • f.read([size]) #size为读取的长度,以byte为单位
  • f.readline([size]) #读一行,如果定义了size,有可能返回的只是一行的一部分
  • f.readlines([size]) #把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长,也就是说可能只读到文件的一部分。
  • f.write(str) #把str写到文件中,write()并不会在str后加上一个换行符
  • f.writelines(seq) #把seq的内容全部写到文件中(多行一次性写入)。这个函数也只是忠实地写入,不会在每行后面加上任何东西。
  • f.close() #关闭文件。python会在一个文件不用后自动关闭文件,不过这一功能没有保证,最好还是养成自己关闭的习惯。 如果一个文件在关闭后还对其进行操作会产生ValueError fp.flush() #把缓冲区的内容写入硬盘

三、文件夹操作

文件夹操作一般使用python的os模块。

  • 1.得到当前工作目录,即当前Python脚本工作的目录路径:os.getcwd()

  • 2.返回指定目录下的所有文件和目录名:os.listdir()

  • 3.函数用来删除一个文件:os.remove()

  • 4.检验给出的路径是否是一个文件:os.path.isfile()

  • 5.检验给出的路径是否是一个目录:os.path.isdir()

  • 6.判断是否是绝对路径:os.path.isabs()

  • 7.检验给出的路径是否真地存:os.path.exists()

  • 8.返回一个路径的目录名和文件名:os.path.split()

    >>> os.path.split('D:\workspace\PythonWork\logger.py')
    ('D:\\workspace\\PythonWork', 'logger.py')
  • 9.分离扩展名:os.path.splitext()

    >>> os.path.splitext('D:\workspace\PythonWork\middleclient\logger.py')
    ('D:\\workspace\\PythonWork\\middleclient\\logger', '.py')
  • 10.获取路径名:os.path.dirname()

    >>> os.path.dirname('D:\workspace\PythonWork\middleclient\logger.py')
    'D:\\workspace\\PythonWork\\middleclient'
  • 11.获取文件名:os.path.basename()

    >>> os.path.basename('D:\workspace\PythonWork\middleclient\logger.py')
    'logger.py'
  • 12.重命名:os.rename(old, new)

  • 13.创建多级目录:os.makedirs(r”c:\python\test”)

  • 14.创建单个目录:os.mkdir(”test”)

  • 15.获取文件大小:os.path.getsize(filename)


python线程

一、线程

Python的标准库提供了两个模块:threadthreadingthread是低级模块,threading是高级模块,对thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。

python的线程有两种方式,直接传入要运行的方法或从Thread继承并覆盖run()

# coding:utf-8
import threading
import time
#方法一:将要执行的方法作为参数传给Thread的构造方法
def action(arg):
    time.sleep(1)
    print 'the arg is:%s\r' %arg

for i in xrange(4):
    t =threading.Thread(target=action,args=(i,))
    t.start()

print 'main thread end!'

#方法二:从Thread继承,并重写run()
class MyThread(threading.Thread):
    def __init__(self,arg):
        super(MyThread, self).__init__()#注意:一定要显式的调用父类的初始化函数。
        self.arg=arg
    def run(self):#定义每个线程要运行的函数
        time.sleep(1)
        print threading.current_thread().getName()

for i in xrange(4):
    t =MyThread(i)
    t.start()

print 'main thread end!'

创建线程的两种方法

构造方法:

Thread(group=None, target=None, name=None, args=(), kwargs={})
  group: 线程组,目前还没有实现,库引用中提示必须是None;
  target: 要执行的方法;
  name: 线程名;
  args/kwargs: 要传入方法的参数。

实例方法:

  • isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。
  • get/setName(name): 获取/设置线程名。
  • start(): 线程准备就绪,等待CPU调度
  • is/setDaemon(bool): 获取/设置是后台线程(默认前台线程(False))。(在start之前设置)
      如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止,如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
  • start(): 启动线程。
  • join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。

二、线程同步

线程经常会有同步问题,python中同步锁是通过threading.Lock()来创建的。

import time,threading

count = 0

lock = threading.Lock()

def add(n):
    global count
    count += n
    count -= n

def run_thread(n):
    for i in range(1000):
        # 先要获取锁
        lock.acquire()
        try:
            add(n)
        finaly:
            lock.release() #改完一定要释放锁

t1 = threading.Thread(target=run_thread, args=(3,))
t2 = threading.Thread(target=run_thread, args=(2,))
t1.start()
t2.start()
t1.join()
t2.join()
print count

如以上例子,如果你不加锁,那么count有可能不会是你想要的结果。

三、线程池

python自带的线程池是threadpool,我们来看看它的用法:

import threadpool

def func(a):
    a = a+1

params = [2,4,6,8]

pool = threadpool.ThreadPool(10)
reqs = threadpool.makeRequests(func, params)
[pool.putRequest(req) for req in reqs]

params可以是一个参数,也可以是一个数组,如果是一个数组就对应一组请求。

如上代码所示,params有4个数据,就会对应创建四个请求,线程池会有对应线程去执行这4个请求。

当然我们也可以自定义线程池

class ThreadPoolManger():
    """线程池管理器"""

    def __init__(self, thread_num):
        # 初始化参数
        self.work_queue = Queue()
        self.thread_num = thread_num
        self.__init_threading_pool(self.thread_num)

    def __init_threading_pool(self, thread_num):
        # 初始化线程池,创建指定数量的线程池
        for i in range(thread_num):
            thread = ThreadManger(self.work_queue)
            thread.start()

    def add_job(self, func, *args):
        # 将任务放入队列,等待线程池阻塞读取,参数是被执行的函数和函数的参数
        self.work_queue.put((func, args))


class ThreadManger(threading.Thread):
    """定义线程类,继承threading.Thread"""

    def __init__(self, work_queue):
        threading.Thread.__init__(self)
        self.work_queue = work_queue
        self.daemon = True

    def run(self):
        # 启动线程
        while True:
            target, args = self.work_queue.get()
            target(*args)
            self.work_queue.task_done()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值