第三章
3.3 文件读取与写入
5)写入文件
我们有时候需要将一些内容写入文件中:
>>>with open('out_file.txt', 'w', encoding='utf-8') as output_file:
output_file.write('Good Good Study' + '\n')
output_file.write('Day Day Up!')
然后我们打开out_file.txt会看到:
Good Good Study
Day Day Up!
通过向open()方法中传入参数"w"
,告诉python我们要以写入模式打开这个文件。这里有三个常用模式可以选择:"r"
只读模式,"w"
写入模式,"a"
附件模式,"r+"
读取和写入。
不加这项参数的情况下,默认是以"r"
只读模式打开的文件,文件不存在时会报错;
"w"
写入模式让我们可以向文件中写入内容,如果文件不存在,则会创建新文件,但是若文件已存在则会先清除文件内容;
"a"
附件模式则是向文件末尾加入新内容,即不影响原来已存在的内容,同样若是文件不存在,则会新建文件;
"r+"
读取和写入模式,就是即可以读取,又可以写入,不会写入不会影响原文件内容。
后面的参数encoding='utf-8'
,指定文件的编码方式,一般加上较保险。
然后我们通过write()
方法向文件写入字符内容,需要注意的是write()方法接受的是字符串格式(<class 'str'>)
,所以我们可以通过对字符串的操作来写入我们希望的内容,但要注意的是,要在每行的最后,加上换行符"\n"
,否则我们希望写入的内容是不会分行的。
除了write()
方法外,还有writelines()
方法,它接受的是可迭代对象,即列表元组等,它将可迭代对象中的元素分别写入文件的每一行,但要注意的还是,要在每个元素后面预先加入换行符"\n"
。
>>>seq = ('aaaaaa\n', 'bbbbb')
>>>with open('out_file2.txt', 'w', encoding='utf-8') as output_file2:
output_file2.writelines(seq)
6)seek()方法
就像我们通过光标控制在word中编辑文档的插入位置一样,python同样具有自己的"光标"——"句柄"
,可以决定读取或者写入内容的位置:
>>>with open('out_file2.txt', 'r+', encoding='utf-8') as output_file2:
output_file.seek(0)
output_file.write('cccc')
seek()函数可以移动句柄位置,常用的参数有(0, 1, 2),0-文件开头,1-当前位置,2-文件结尾。注意,当向文件中写入数据时,如果不是文件的尾部,写入位置的原有数据不会自行向后移动,新写入的数据会将文件中处于该位置的数据直接覆盖掉。所以上面的例子中,新写入的'cccc'
会覆盖掉原文件中的'aaaaaa'
。
要查看句柄所在位置,使用tell()
方法。关于句柄我遇到的使用还不多,回头遇到使用多的情况再回来完善。
7)读取多个文件
有时候我们需要将多个文件的内容一起读取,进行统一的处理,这时候,通过将多个文件名存入一个列表中,然后遍历这个列表中的每个文件名,传入with-open
语句的open()
方法中,就可以对多个文件内容进行读取了。
假设我们要提取多个文件中的序列名称:
>>> name_list = ['1.faa', '2.faa', '3.faa', '4.faa']
>>>for name in name_list:
with open(name) as seqs:
lines4 = [x.rstrip() for x in seqs if x[0] == '>']
对这个函数进一步加工一下,有时候我们要读取的文件可能不存在,使用前面讲过的tyr-except-else
来处理这种情况:
>>> name_list = ['1.faa', '2.faa', '3.faa', '4.faa']
>>>for name in name_list:
try:
seqs = open(name)
except FileNotFoundError:
msg = "The file " + name + " does not exist!"
print(msg)
else:
list_names = [x.rstrip() for x in seqs if x[0] == '>']
seqs.close()
这样,我们不仅可以将序列文件的序列名读取到列表中,python还会告诉我们哪个文件是不存在的。
微生物基因组-关于进化那些事
1,以前人们认为,16s rRNA
差异大于3%
,也就是基因组序列相似性小于70%
,即溶解温度(Δ*T*m)
大于或等于5℃
即被认为是不同的种。然而这种标准正在受到挑战。因为16s rRNA的保守性,某些不同的中可能有相同或者近似的rRNA序列,而且在一些情况下,一个菌株也可能有rRNA基因上的差异。还有,单个细菌细胞内部含有多个rRNA拷贝,在少数情况下,它们有着大于5%的差异。
2,第一个基于16s rRNA的整体生命树是没有根的。因为以rRNA序列作为分析对象,没有一个类群可以延伸为种系的生命树之根。后来,科学家引入了横向同源基因等其他分析对象,才将生命分成了细菌,真核生物和古生菌,古菌和真核生物在一个树枝上。
3,随着获得的分子数据的增加,不同的基因树被构建,但当拿他们与rRNA树进行比较时,却发现有些不一致的地方,对此的一个解释是因为水平基因的转移
(horizontal gene transferm HGT)。遗传信息的交换是微生物进化的一个主要因素,操纵子的形成归因为频繁的基因转移,而基因的获得通常形成基因组的孤岛,这是能使生物占据一个新的生态位的重要因素。
4,基因转移不仅限于种间,甚至能出现在域间。通过分析微生物的全基因组序列发现,HGT广的广泛性随处可见,就连管家基因也可以发生基因转移,事实上所有的基因都可以进行水平转移。
5,即使低频率的基因转移也会导致镶嵌式基因组,而不同镶嵌部分反映了不同的历史,一个分子或者基因树与生物进化之间存在的潜在差异已成为共识。
6,考虑到基因转移的情况,可靠的基因组信息只能对应于现存的微生物,并不能代表过去无限代的生物的真实情况。
7,从不同分子标记得到一致的种系发生关系,说明该物种的这些基因主要是纵向遗传,但并不是说绝对的是,因为有些情况下,水平基因转移同样具有产生一致分子种系发生的潜能。这些一致的分子种系关系并不一定反映生物的种系发生,基因组的镶嵌式特性,使得重建生物世代关系变得困难重重,在有些情况下是不可能的。
8,为了更好的重建物种间的系统发育树,使用更多的基因组信息就显得尤为重要,会在后面介绍如何构建基因全基因组的单拷贝同源序列系统发育树。