python 文件操作和json模块的模块化写法

前言

  python 操作文件的方法有,open 直接打开文件。json,pickle,shelve ,configparser ,都是写入到文件,或者修改文件。

1.python open 打开文件(分别读写)

就以自己写的自动添加目录索引为例子。

原始文件如下:

<ol>
<li><a style="text-decoration:none;color: #000000; line-height: 20px; font-family: 楷体; font-size: 20px;" href="http://www.cnblogs.com/keep-going2099/articles/8134851.html" target="_blank">python 编码格式 </a></li>
</ol>

要求:当有新的url链接需要生成时,在最后一个<li></li>标签后面添加一行数据,或者说是,在</ol>前面添加一个<li></li>标签里面的内容;

先贴代码:

# -*- coding: utf-8 -*-
import io,sys,os
def add_blog_url(url,info):
    add_content = '<li><a  style="text-decoration:none;color: #000000; line-height: 20px; font-family: 楷体; font-size: 20px;" href="%s" target="_blank">%s</a></li>'%(url,info)
    # add_content = '<li><a  href="%" target="_blank"></a></li>'%(url,info)
    li_content = []
    with io.open("blog_url.html", 'r', encoding='utf-8') as  read_file, io.open("new_blog_url.html", 'w',encoding='utf-8') as write_file:
        content = read_file.read()
        post = content.find('</ol>')
        if post != -1:
            content = content[:post] + add_content+'\n' + content[post:]
        '''
        这里就相当于字符串的切片操作,find的意思是,如果找不到就返回-1,找到返回查找的字符串的位置。
        content = content[:post] + add_content + content[post:]
        content[:post] :读取的是查找内容之前内容
        add_content : 表示要添加的内容
        content[post:] :表示查找内容之后的
        '''
        write_file.write(content)
        # os.rename('blog_url.html','bak_blog_url.html')
    os.remove('blog_url.html')
    os.rename('new_blog_url.html','blog_url.html')


if __name__ == '__main__':
    while True:
        url = input("输入网址,退出(Q):").strip()
        if url == 'Q':break
        if len(url) == 0:continue
        if  url.startswith("http://") or url.startswith("https://"):
            info = input("输入网站信息:").strip()
            add_blog_url(url,info)
        else:
            print("必须是http:// 或者https:// 开头才能访问,")
            continue

知识点1:open函数打开文件;

  首先:用with 打开文件时,不需要close文件对象。

  在py2 和py3 中,open打开文件的方法是不同的,区别在于在python2 中不添加 "  encoding='utf-8' ",python3中可以不加,但是,如果加上以后,在py2 中执行就会报错。

  但是,无论是py2还是 py3 的open函数,都是调用了 io 模块下的open函数,因此,直接调用io模块,io.open("blog_url.html", 'r', encoding='utf-8'),这样,无论是在py2 还是py3 都不会报错了!

知识点2:怎么能够在指定字符串之前插入数据。

  原理:在 read_file 文件对象,读取到文件的内容以后,content = read_file.read(),读到的其实是一串字符串。然后用find 找到 指定字符串在 content中第一次出现的位置。然后用 字符串的切片方法进行分割,如下:

str.find("strinfg") 查找字符串,如果没有找到返回 -1 ,找到以后就返回string  在原始字符串中的 postion 位置。    

content = content[:post] + add_content+'\n' + content[post:]
        '''
        这里就相当于字符串的切片操作,find的意思是,如果找不到就返回-1,找到返回查找的字符串的位置。
        content = content[:post] + add_content + content[post:]
        content[:post] :读取的是查找内容之前内容
        add_content : 表示要添加的内容
        content[post:] :表示查找内容之后的
        '''

2. 修改文件的方法(替换)

修改文件两种方式:

1)  直接把要修改的文件内容写到一个新文件,然后在把新文件rename成为一个老文件。

2)  把修改的内容修改以后放到一个列表里面,然后,在把列表里面的内容写到源文件。注意:当要修改的文件,或者说是要替换的字符串的长度大于新字符串的长度时,文件原始的字节长度是不变的,因此 就会出现一部分字符串在修改文件的末尾,因此,此时就要用 文件操作的方法(truncate)来进行截断。因为,当文件修改以后,游标会到修改的那个位置,因此,在游标的位置进行truncate就会把原始文件未被占用的字节长度给截断掉。

方法1:差不多相当于上面的方法,只是自己的实现方式上的小区别修改即可。

方法2:有如下文件,需要把python 替换成为 java

[root@dev second_modules]# cat text.log
hello world!
everyday study python
l like python
do you love python?

代码如下:读到内存,然后再写到源文件

[root@dev second_modules]# cat modify_file_free.py
#!/usr/bin/env python
#coding:utf-8
f_name = "text.log"
old_str = "python"
new_str = "java"
f = open(f_name,'r+',encoding="utf-8")
list01 = []
for line in f:
   if old_str in line:
      line = line.replace(old_str,new_str)
   list01.append(line)
values = ''.join(list01)
print(values)
f.seek(0)
f.write(values)
f.truncate()
f.close()

** 上面红色字体的  truncate的意思就是,列表内容写完以后,假如源文件的字节长度大于现在的字节长度,那么就把现在的字节长度写完以后,进行截断。因为,不管是读还是写都是在源文件的基础上去进行的,源文件的原始字节长度不会改变。如果不进行截断,那么就会多出源文件的一部分字节出来。演示方法去掉truncate即可,并且替换的字节长度小于要替换的字节长度。

用更通俗的话来讲:首先读,会把整个文件读完,那么文件指针就会走到文件内容的末尾。不可能继续读,然后,f.seek(0),把文件指针重新放到文件头部,此时写的时候,就相当于 ”w“ 方法了。因此,可以直接写。truncate 只是为了截取就文件多余的字节长度。

3.python 的json 模块的,模块化写法

json其实读取文件和写入文件具体用法可以查看 python笔记,但是,为什么还要继续写这个笔记呢?

因为,在写python程序的时候,很多次的会用到 json模块的读方法和写放啊。因此,为何不在json的基础上,直接写一个你想要打开的文件的方法呢。

代码如下:

#coding:utf-8

import os
import io
import json
import sys

'''
该模块使用方法:
operate_user_info_file(filename,mode,dirname=default_path,data=None)
filename:文件名(可以用用户的名称作为文件名)
mode:参数用:read 或者  write
dirname:默认是写到conf目录下,但是,也可以自己写指定的路径。
data: 是用于写方法时,写入文件的数据。
正确调用方法:
1.读:operate_file('ryan','read') 或者,自己自己目录读取 operate_user_info_file(filename,mode,dirname=yourdir)
2.写:operate_file('ryan','write',data="yourdata"),如果要指定路径写,也是和读一样自己指定路径。
'''
if os.name == 'posix':
    default_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/'+'conf'
elif os.name == 'nt':
    default_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '\\'+'conf'

def operate_file(filename,mode,dirname=default_path,data=None):
    if mode == 'write':
        write_file = io.open("%s/%s.json"%(dirname,filename),'w',encoding='utf-8')
        json.dump(data,write_file)
        write_file.close()
        return True,"写入成功"
    elif mode == 'read':
        filename = "%s/%s.json" % (dirname, filename)
        # print(filename)
        if os.path.isfile(filename) and os.path.exists(filename):
            read_file = io.open(filename, 'r', encoding='utf-8')
            return_data = json.load(read_file)
            read_file.close()
            return return_data
        else:
            return False

if __name__ == '__main__':

    res = operate_file("ryan2",'read')
    if res:
        print("文件存在")
    else:
        print("not exists")

 

 

  

 

posted @ 2017-12-28 15:54  Nice_keep-going  阅读(259)  评论(0编辑  收藏  举报