dbdb学习记录

dbdb学习记录

关于__all__的用法

  1. __init__.py文件中,__all__=[“module_a”,”module_b”]

    在使用 from package_name import * 时 , 表示import该package中的两个module及两个module相关的类、方法等。

  2. 在普通py文件中,__all__=[“class_name”,”function_name”]

    在使用 from module_name import * 时,表示import该module中的__all__中所列出的。

注意事项

  1. 在普通的.py中, 使用 all 时,可以使用all*列出的 类、函数、变量等,不使用_all_时会使用module中的所有不以下划线开头的成员。

  2. __all__只能影响到 from import * 这种import 方式, 对于from … import … 方式没有影响。

  3. __all__ 的数据类型: list

文件打开方式

open()

  • Built-in open() takes a file name and returns a new Python file object. This is what you need in the majority of cases.

os.open()

  • os.open() takes a file name and returns a new file descriptor. This file descriptor can be passed to other low-level functions, such as os.read() and os.write(), or to os.fdopen(), as described below. You only need this when writing code that depends on operating-system-dependent APIs, such as using the O_EXCL flag to open(2).
  • os.O_RDWR : 以读写的方式打开
  • os.O_CREAT: 创建并打开一个新文件
  • os.O_RDONLY: 以只读的方式打开
  • os.O_WRONLY: 以只写的方式打开

os.fdopen()

  • os.fdopen() takes an existing file descriptor — typically produced by Unix system calls such as pipe() or dup(), and builds a Python file object around it. Effectively it converts a file descriptor to a full file object, which is useful when interfacing with C code or with APIs that only create low-level file descriptors.
  • os.fdopen(fd, [, model[, bufsize]]) 方法用于通过文件描述符 fd 创建一个文件对象,并返回这个文件对象。
  • mode 可选,mode参数可以指定『r,w,a,r+,w+,a+,b』等,表示文件的是只读的还是可以读写的,以及打开文件是以二进制还是文本形式打开。

conclusion

Built-in open can be implemented using os.open() (to create a file descriptor(文件描述符)) and os.fdopen() (to wrap it in a file object(文件对象)):

1
2
># equivalent to f = open(filename, "r")
>f = os.fdopen(os.open(filename, os.O_RDONLY))

摘自stackoverflow

文件锁

为了避免在多进程时同时操作文件,需要程序在操作文件前先上锁。

  • LOCK_SH:表示要创建一个共享锁,在任意时间内,一个文件的共享锁可以被多个进程拥有;
  • LOCK_EX:表示创建一个排他锁,在任意时间内,一个文件的排他锁只能被一个进程拥有;
1
2
import portalocker
portalocker.lock(file_descriptor, portalocker.LOCK_EX)

定位文件位置

seek(offset,whence):移动文件指针

  • offset:偏移量,可以是负数代表往前移动指针
  • whence:偏移相对位置

文件指针定位的whence有三种:

  • os.SEEK_SET:相对文件起始位置
  • os.SEEK_CUR:相对文件当前位置
  • os.SEEK_END:相对文件结尾位置
  • f.seek(10, os.SEEK_SET) # 将文件指针指向文件开始的第10个位置
  • f.seek(-10, os.SEEK_END) # 将文件指针指向文件末尾向前的第10个位置
  • f.seek(10) # 将文件指针指向文件开始的第10个位置#

文件读写函数

  • f.read(10)从文件指针当前指向的位置读取10位,没给参数代表读完。
  • f.tell()查看文件指针当前指向的位置
  • f.flush():文件写入有个缓存机制,如果文件的长度小于这个文件的缓存的size,它会先放在缓存中,调用close或者flush函数才会写入到磁盘。当写入的文件大于这个文件的系统缓存,它会先把写满缓存的同时写入磁盘,这个时候查看文件已经写入了,不用调用close或者flush方法。

@property使用方法

python内置的@property装饰器就是负责把一个方法变成属性调用,这样可以不把属性直接暴露出去,而是通过函数来返回或者设置属性的值。例如

1
2
3
4
5
6
7
8
9
10
11
12
13
class Student(object):
@property
def score(self):
return self._score


@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value

此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,如果不设置setter方法就只是一个只读属性

1
2
3
4
5
6
7
8
>>> s = Student()
>>> s.score = 60 # 实际转化为s.set_score(60)
>>> s.score # 实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
...
ValueError: score must between 0 ~ 100!

摘自廖雪峰的官方网站