[python]你真的理解open函数吗?

open函数是python的一个内置函数,用于打开一个文件,创建一个 file 对象。

但是,你真的懂open函数吗?

先来看看网上的教程:

函数语法

open(name[, mode[, buffering]])

参数说明:

  • name : 一个包含了你要访问的文件名称的字符串值。

  • mode : mode 决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。

  • buffering : 如果 buffering 的值被设为 0,就不会有寄存。如果 buffering 的值取 1,访问文件时会寄存行。如果将 buffering 的值设为大于 1 的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。

不同模式打开文件的完全列表:

模式描述
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

file 对象方法

  • file.read([size]):size 未指定则返回整个文件,如果文件大小 >2 倍内存则有问题,f.read()读到文件尾时返回""(空字串)。

  • file.readline():返回一行。

  • file.readlines([size]) :返回包含size行的列表, size 未指定则返回全部行。

  • for line in f: print line :通过迭代器访问。

  • f.write("hello\n"):如果要写入字符串以外的数据,先将他转换为字符串。

  • f.tell():返回一个整数,表示当前文件指针的位置(就是到文件头的比特数)。

  • f.seek(偏移量,[起始位置]):用来移动文件指针。

    • 偏移量: 单位为比特,可正可负

    • 起始位置: 0 - 文件头, 默认值; 1 - 当前位置; 2 - 文件尾

  • f.close() 关闭文件

 

看完了教程,有编程经验的人是不是觉得so easy,我也觉得非常的简单。

但是,我在工作中就掉进了这个坑里,只能说自己对open函数理解的还不够,也说明了自己的基础确实不好。唉,要好好补补基础了,基础扎实才走得稳走得远呀!

先来看看导致bug的代码吧

cache_dir = os.path.join(os.path.dirname(__file__), '../../', 'cache')
if not os.path.exists(cache_dir):
  os.makedirs(cache_dir)
cache_path = os.path.join(cache_dir, 'sign_token_ticket.json')
if not os.path.exists(cache_path):
  with open(cache_path, 'w') as f:
    sign_token_ticket = dict(
      token={
        'value': '',
        'expire': 0
      },
      ticket = {
        'value': '',
        'expire': 0
      }
    )
else:
  with open(cache_path) as f:
    if f.read():
      sign_token_ticket = json.loads(f.read())
    else:
      sign_token_ticket = dict(
        token={
          'value': '',
          'expire': 0
        },
        ticket={
          'value': '',
          'expire': 0
        }
      )

这是一段缓存token的逻辑代码,用来保存有效期的token,如果失效就重新获取,本来是打算存储到数据库的,但是有点用杀牛刀来宰鸡的感觉,所以就保存在文件里。不知道看完代码后的你,有没有发现问题在哪里。

就是以上代码导致bug的出现,我先判断文件里有没有内容,如果有内容就获取文件里的内容。

殊不知,在第一次使用f.read()的时候,文件指针就指向了文件尾,再次使用f.read()读取内容的时候就为空了。

这就是忽略了细节,和基础不扎实,哭唧唧。

既然发现了问题,那就改吧,先读取到内容赋值给一个变量,再对这个变量做判断,这样就可以做到只读一次。

 

关注公众号:日常bug,每天至少一篇技术文章,适合技术点滴积累,利用琐碎时间学习技术的人。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值