文件操作
一. 文件的基本操作
1.1 文件的打开—open()
你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。
语法:
file object = open(file_name [, access_mode][, buffering])
各个参数的细节如下:
- file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
- access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读®。
- buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。
不同模式打开文件的完全列表:
模式 | 描述 |
---|---|
t | 文本模式 (默认)。 |
x | 写模式,新建一个文件,如果该文件已存在则会报错。 |
b | 二进制模式。 |
+ | 打开一个文件进行更新(可读可写)。 |
U | 通用换行模式(不推荐)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
下图很好的总结了这几种模式:
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
程序示例:
open('test.txt','r') # r 只能打开已存在文件,并且只读
open('D:\\test.txt','w') # w 文件不存在则创建,存在则创建并覆盖
open(r'D:\test\text.txt','a') # a 文件存在则打开 只写
注意问题:
在写文件路径时,有时候会发生如下报错等情况
Traceback (most recent call last):
File "C:\Users\admin\Desktop\new.py", line 1, in <module>
open(r'test.txt','r')
FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
这个就是没有找到该文件或者文件夹,很有可能是文件路径格式填错,以下是部分解决办法:
解决方式一: ‘C:\\Users\\Luokk\\Desktop\\111.txt’ 将一个反斜杠换成两个反斜杠,多加一个\ 这样就是前面\对后面的\进行转译,告诉计算机这个只是想单纯的表示\路径而已。
解决方法二: r’C:\Users\Luokk\Desktop\111.txt’ 在路径的整体前面加一个r。(推荐)
相对路径与绝对路径:
1.绝对路径:从磁盘根目录开始一直到文件名
2.相对路径:用一个文件夹下的文件,相对于当前这个程序所在的文件而言.如果在同一个文件中,则相对路劲就是这个文件名.如果再上一层文件夹则要使用…/相对路径下,你就可以直接写文件名即可。
1.2 文件的写入—write()和writelines()
1.2.1 单行写入 write()
write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不是仅仅是文字。
write()方法不会在字符串的结尾添加换行符(’\n’):
语法格式:
file.write(string)
其中,file 表示已经打开的文件对象;string 表示要写入文件的字符串(或字节串,仅适用写入二进制文件中)
注意,在使用 write() 向文件中写入数据,需保证使用 open() 函数是以 r+、w、w+、a 或 a+ 的模式打开文件,否则执行 write() 函数会抛出 io.UnsupportedOperation 错误。
例如,创建一个 test.txt 文件,该文件内容如下:
hello world
欢迎来到空空的世界
然后,在和 test.txt 文件同级目录下,创建一个 Python 文件,编写如下代码:
f = open("test.txt", 'w') #打开文件
f.write("写入一行新数据") #写入内容
f.close() #关闭文件
前面已经讲过,如果打开文件模式中包含 w(写入),那么向文件中写入内容时,会先清空原文件中的内容,然后再写入新的内容。因此运行上面程序,再次打开 test.txt 文件,只会看到新写入的内容:
写入一行新数据
而如果打开文件模式中包含 a(追加),则不会清空原有内容,而是将新写入的内容会添加到原内容后边。例如,还原 test.txt 文件中的内容,并修改上面代码为:
f = open("test.txt", 'a') #打开文件
f.write("\n写入一行新数据") #写入内容
f.close() #关闭文件
再次打开 test.txt,可以看到如下内容:
hello world
欢迎来到空空的世界
写入一行新数据
因此,采用不同的文件打开模式,会直接影响 write() 函数向文件中写入数据的效果。
另外,在写入文件完成后,一定要调用 close() 函数将打开的文件关闭,否则写入的内容不会保存到文件中。例如,将上面程序中最后一行 f.close() 删掉,再次运行此程序并打开 test.txt,你会发现该文件是空的。这是因为,当我们在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 函数时,操作系统才会保证把没有写入的数据全部写入磁盘文件中。
除此之外,如果向文件写入数据后,不想马上关闭文件,也可以调用文件对象提供的 flush() 函数,它可以实现将缓冲区的数据写入文件中。例如:
f = open("test.txt", 'w') #打开文件
f.write("写入一行新数据") #写入内容
f.flush() #保存文件
打开 test.txt 文件,可以看到写入的新内容:
写入一行新数据
有读者可能会想到,通过设置 open() 函数的 buffering 参数可以关闭缓冲区,这样数据不就可以直接写入文件中了?对于以二进制格式打开的文件,可以不使用缓冲区,写入的数据会直接进入磁盘文件;但对于以文本格式打开的文件,必须使用缓冲区,否则 Python 解释器会 ValueError 错误。例如:
f = open("test.txt", 'w',buffering = 0)
f.write("写入一行新数据")
运行结果为:
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\demo.py", line 1, in <module>
f = open("a.txt", 'w',buffering = 0)
ValueError: can't have unbuffered text I/O
1.2.2 多行写入 writelines()
writelines() 方法用于向文件中写入一序列的字符串。
这一序列字符串可以是由迭代对象产生的,如一个字符串列表。
换行需要制定换行符 \n
语法格式:
file.writelines( [ str ])
程序示例:
f = open("test.txt", 'w') #打开文件
f.writelines(['My\n','name\n','is\n','luokk']) #写入内容
f.flush() #关闭文件
打开 test.txt,可以看到如下内容:
My
name
is
luokk
1.3 文件的关闭—close()
file_one.flush()
文件最开始写入会写入到内存中,只有调用flush刷新到硬盘中才能保存到文件
file_one.close()
关闭文件也会自动保存修改到文件中
1.4 文件的读取—read() 和 readline()
1.4.1 read()
对于借助 open() 函数,并以可读模式(包括 r、r+、rb、rb+)打开的文件,可以调用 read() 函数逐个字节(或者逐个字符)读取文件中的内容。
如果文件是以文本模式(非二进制模式)打开的,则 read() 函数会逐个字符进行读取;反之,如果文件以二进制模式打开,则 read() 函数会逐个字节进行读取。
read() 函数的基本语法格式如下:
file.read([size])
其中,file 表示已打开的文件对象;size 作为一个可选参数,用于指定一次最多可读取的字符(字节)个数,如果省略,则默认一次性读取所有内容。
举个例子,首先创建一个名为 luokk.txt 的文本文件,其内容为:
Python教程
https://blog.csdn.net/kc44601
然后在和luokk.txt 同目录下,创建一个 file.py 文件,并编写如下语句:
f = open("luokk.txt",encoding = "utf-8") #以 utf-8 的编码格式打开指定文件
print(f.read()) #输出读取到的数据
f.close() #关闭文件
程序运行结果为:
Python教程
https://blog.csdn.net/kc44601
注意,当操作文件结束后,必须调用 close() 函数手动将打开的文件进行关闭,这样可以避免程序发生不必要的错误。
当然,我们也可以通过使用 size 参数,指定 read() 每次可读取的最大字符(或者字节)数,例如:
f = open("luokk.txt",encoding = "utf-8") #以 utf-8 的编码格式打开指定文件
print(f.read(6)) #输出读取到的数据
f.close() #关闭文件
运行结果为:
Python
显然,该程序中的 read() 函数只读取了 my_file 文件开头的 6 个字符。
再次强调,size 表示的是一次最多可读取的字符(或字节)数,因此,即便设置的 size 大于文件中存储的字符(字节)数,read() 函数也不会报错,它只会读取文件中所有的数据。
除此之外,对于以二进制格式打开的文件,read() 函数会逐个字节读取文件中的内容。例如:
f = open("luokk.txt",'rb+') #以二进制形式打开指定文件
print(f.read()) #输出读取到的数据
f.close() #关闭文件
运行结果:
b'Python\xe6\x95\x99\xe7\xa8\x8b\r\nhttps://blog.csdn.net/kc44601'
1.4.2 按行读取文件 readline() 和 readlines()
和 read() 函数不同,这 2 个函数都以“行”作为读取单位,即每次都读取目标文件中的一行。对于读取以文本格式打开的文件,读取一行很好理解;对于读取以二进制格式打开的文件,它们会以“\n”作为读取一行的标志。
readline()函数
readline() 函数用于读取文件中的一行,包含最后的换行符“\n”。此函数的基本语法格式为:
file.readline([size])
其中,file 为打开的文件对象;size 为可选参数,用于指定读取每一行时,一次最多读取的字符(字节)数。
和 read() 函数一样,此函数成功读取文件数据的前提是,使用 open() 函数指定打开文件的模式必须为可读模式(包括 r、rb、r+、rb+ 4 种)。
仍以前面章节中创建的 luokk.txt 文件为例,该文件中有如下 2 行数据:
Python教程
https://blog.csdn.net/kc44601
下面程序演示了 readline() 函数的具体用法:
f = open("luokk.txt",encoding = "utf-8")
byt = f.readline() #读取一行数据
print(byt)
运行结果:
Python教程
由于 readline() 函数在读取文件中一行的内容时,会读取最后的换行符“\n”,再加上 print() 函数输出内容时默认会换行,所以输出结果中会看到多出了一个空行。
不仅如此,在逐行读取时,还可以限制最多可以读取的字符(字节)数,例如:
f = open("luokk.txt",'rb') #以二进制形式打开指定文件
byt = f.readline(6)
print(byt)
运行结果:
b'Python'
和上一个例子的输出结果相比,由于这里没有完整读取一行的数据,因此不会读取到换行符。
readlines()函数
readlines() 函数用于读取文件中的所有行,它和调用不指定 size 参数的 read() 函数类似,只不过该函数返回是一个字符串列表,其中每个元素为文件中的一行内容。
和 readline() 函数一样,readlines() 函数在读取每一行时,会连同行尾的换行符一块读取。
readlines() 函数的基本语法格式如下:
file.readlines()
其中,file 为打开的文件对象。和 read()、readline() 函数一样,它要求打开文件的模式必须为可读模式(包括 r、rb、r+、rb+ 4 种)。
程序示例:
f = open("luokk.txt",encoding = "utf-8")
byt = f.readlines()
print(byt)
运行结果:
['Python教程\n', 'https://blog.csdn.net/kc44601']
注意:是编码格式,因为我们文件中可能会写入中文,如果直接读取会出现乱码情况:
例如:
f = open("luokk.txt")
byt = f.readlines()
print(byt)
运行结果:
['Python鏁欑▼\n', 'https://blog.csdn.net/kc44601']
此处中文输出为乱码,因此在打开文件时最好加上编码格式,下面我们改写上面代码:
f = open("luokk.txt",encoding = "utf-8")
byt = f.readlines()
print(byt)
运行结果:
['Python教程\n', 'https://blog.csdn.net/kc44601']
1.5 with open () as 用法
前面在介绍文件操作时,一直强调打开的文件最后一定要关闭,否则会程序的运行造成意想不到的隐患。但是,即便使用 close() 做好了关闭文件的操作,如果在打开文件或文件操作过程中抛出了异常,还是无法及时关闭文件。
使用 with as 操作已经打开的文件对象(本身就是上下文管理器),无论期间是否抛出异常,都能保证 with as 语句执行完毕后自动关闭已经打开的文件。
with as 语句的基本语法格式为:
with 表达式 [as target]:
代码块
此格式中,用 [] 括起来的部分可以使用,也可以省略。其中,target 参数用于指定一个变量,该语句会将 expression 指定的结果保存到该变量中。with as 语句中的代码块如果不想执行任何语句,可以直接使用 pass 语句代替。
举个例子,假设有一个 luokk.txt 文件,其存储内容如下:
Python教程
https://blog.csdn.net/kc44601
在和 luokk.txt 同级目录下,创建一个 .py 文件,并编写如下代码:
with open('luokk.txt','a',encoding = "utf-8") as f:
f.write("\n欢迎来到空空的世界")
运行后,luokk.txt文件内的内容如下:
Python教程
https://blog.csdn.net/kc44601
欢迎来到空空的世界
1.6 文件指针 seek() 和 tell()
我们知道,使用 open() 函数打开文件并读取文件中的内容时,总是会从文件的第一个字符(字节)开始读起。那么,有没有办法可以自定指定读取的起始位置呢?答案是肯定,这就需要移动文件指针的位置。
文件指针用于标明文件读写的起始位置。假如把文件看成一个水流,文件中每个数据(以 b 模式打开,每个数据就是一个字节;以普通模式打开,每个数据就是一个字符)就相当于一个水滴,而文件指针就标明了文件将要从文件的哪个位置开始读起。下图简单示意了文件指针的概念。
可以看到,通过移动文件指针的位置,再借助 read() 和 write() 函数,就可以轻松实现,读取文件中指定位置的数据(或者向文件中的指定位置写入数据)。
注意,当向文件中写入数据时,如果不是文件的尾部,写入位置的原有数据不会自行向后移动,新写入的数据会将文件中处于该位置的数据直接覆盖掉。
实现对文件指针的移动,文件对象提供了 tell() 函数和 seek() 函数。tell() 函数用于判断文件指针当前所处的位置,而 seek() 函数用于移动文件指针到文件的指定位置。
tell() 函数
tell() 函数的用法很简单,其基本语法格式如下:
file.tell()
其中,file 表示文件对象。
例如,在同一目录下,编写如下程序对 luokk.txt 文件做读取操作,luokk.txt 文件中内容为:
Python教程
https://blog.csdn.net/kc44601
欢迎来到空空的世界
读取 luokk.txt 的代码如下:
f = open("luokk.txt",'r')
print(f.tell())
print(f.read(3))
print(f.tell())
运行结果为:
0
Pyt
3
可以看到,当使用 open() 函数打开文件时,文件指针的起始位置为 0,表示位于文件的开头处,当使用 read() 函数从文件中读取 3 个字符之后,文件指针同时向后移动了 3 个字符的位置。这就表明,当程序使用文件对象读写数据时,文件指针会自动向后移动:读写了多少个数据,文件指针就自动向后移动多少个位置。
seek() 函数
seek() 函数用于将文件指针移动至指定位置,该函数的语法格式如下:
file.seek(offset[, whence])
其中,各个参数的含义如下:
- file:表示文件对象;
- whence:作为可选参数,用于指定文件指针要放置的位置,该参数的参数值有 3 个选择:0 代表文件头(默认值)、1 代表当前位置、2 代表文件尾。
- offset:表示相对于 whence 位置文件指针的偏移量,正数表示向后偏移,负数表示向前偏移
例如,
当whence == 0 &&offset == 3(即 seek(3,0) ),表示文件指针移动至距离文件开头处 3 个字符的位置;
当whence == 1 &&offset == 5(即 seek(5,1) ),表示文件指针向后移动,移动至距离当前位置 5 个字符处。
注意,当 offset 值非 0 时,Python 要求文件必须要以二进制格式打开,否则会抛出 io.UnsupportedOperation 错误。
下面程序示范了文件指针操作:
f = open('luokk.txt', 'rb')
# 判断文件指针的位置
print(f.tell())
# 读取一个字节,文件指针自动后移1个数据
print(f.read(1))
print(f.tell())
# 将文件指针从文件开头,向后移动到 5 个字符的位置
f.seek(5)
print(f.tell())
print(f.read(1))
# 将文件指针从当前位置,向后移动到 5 个字符的位置
f.seek(5, 1)
print(f.tell())
print(f.read(1))
# 将文件指针从文件结尾,向前移动到距离 2 个字符的位置
f.seek(-1, 2)
print(f.tell())
print(f.read(1))
运行结果为:
0
b'P'
1
5
b'n'
11
b'\x8b'
71
b'\x8c'
注意:由于程序中使用 seek() 时,使用了非 0 的偏移量,因此文件的打开方式中必须包含 b,否则就会报 io.UnsupportedOperation 错误,有兴趣的读者可自定尝试。
二. 文件流
刚才讲的永久的文件存储,那如果文件需要快速大量的读取呢?
import io
string_io = io.StringIO()
在内存中打开一个文件流,如同打开一个文件
文件流有getvalue方法可以获取内容
程序示例:
import io
string_io = io.StringIO()
string_io.write("this is pthon string io")
print(string_io.getvalue())
运行结果:
this is pthon string io
BytesIO 和StringIO类似,区别是内容都是二进制的字符串
主要用来存储图像、音频、视频等
程序示例:
import io
byte_io = io.BytesIO()
byte_io.write(b'abcd')
print(byte_io.getvalue())
运行结果:
b'abcd'
三. 文件目录操作
刚才我们是对单个文件的操作,如果我们需要对文件所在的文件目录操作该怎么做呢?
程序示例:
import os #和操作系统交互,需要用到os模块
print(os.getcwd()) #获取当前路径
print(os.chdir(r'C:\Users\admin\Desktop\python')) #切换路径
print(os.listdir(path='.')) #查看文件和子目录,默认是当前目录
运行结果:
C:\Users\admin\Desktop
None
['e_books', 'linux', 'ps.docx', 'py', 'Python3萌新入门笔记', 'QQ截图20200830213337.png', 'web.txt', 'web前端', '基础班', '网络编程', '进阶版']
也支持对文件目录的操作
import os
os.mkdir('file') #创建文件夹
os.rename('file','new_file') #对文件夹重命名
运行该程序后,在与本.py文件同级的目录内会多了一个名为 new_file 的文件夹
还有以下方法:
makedires #创建多层目录
remove #移动文件
rmdir #删除目录
removedirs #删除多层目录
system #调用系统命令
walk #遍历文件夹
os.path #路径操作
更多文件目录操作请参考:文件目录操作
四. 模块和包
4.1 模块(Module)
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你能够有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
4.1.1import 语句
模块的引入
模块定义好后,我们可以使用 import 语句来引入模块,语法如下:
import module1[, module2[,... moduleN]]
比如要引用模块 math,就可以在文件最开始的地方用 import math 来引入。在调用 math 模块中的函数时,必须这样引用:
模块名.函数名
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。
4.1.2 from…import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:
from fib import fibonacci
这个声明不会把整个 fib 模块导入到当前的命名空间中,它只会将 fib 里的 fibonacci 单个引入到执行这个声明的模块的全局符号表。
4.1.3 from…import*语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
from modname import *
这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
例如我们想一次性引入 math 模块中所有的东西,语句如下:
from math import *
4.1.4 路径的添加
import sys
sys.path
使用sys.path来查看模块的查找路径
如果要添加其他的路径,只需要使用:
sys.path.append(path)将路径添加列表即可
程序示例:
import sys
print(sys.path)
sys.path.append('aaa')
print(sys.path)
运行结果:
['C:\\Users\\admin\\Desktop', 'D:\\python\\python38.zip', 'D:\\python\\DLLs', 'D:\\python\\lib', 'D:\\python', 'C:\\Users\\admin\\AppData\\Roaming\\Python\\Python38\\site-packages', 'D:\\python\\lib\\site-packages']
['C:\\Users\\admin\\Desktop', 'D:\\python\\python38.zip', 'D:\\python\\DLLs', 'D:\\python\\lib', 'D:\\python', 'C:\\Users\\admin\\AppData\\Roaming\\Python\\Python38\\site-packages', 'D:\\python\\lib\\site-packages', 'aaa']
__name__代表模块的名字
__main__当模块直接运行时的文件名
当文件被导入时,if判断返回False
sys.argv 获取参数传入
import sys
print('not in main')
if __name__ == '__main__':
print('in main')
print(sys.argv)
运行结果:
not in main
in main
['C:\\Users\\admin\\Desktop\\new.py']
4.2 包
import json
所谓的包,就是存放多个模块的文件夹
Python中的包,值得就是一个py文件夹
包管理
1、init.py可以设置包的信息,比如:__all__设置外界可以查看的包的方法
2、包内的模块相互导入使用:from .module/…module import obj(as new_name)
3、模块出现相对路径导入,则只可以被导入,不能直接运行
五. 作业
本节作业:
1、利用datetime模块,批量生成6月份每天的txt文件
2、生成上面的文件之后,再一次在每个文件中写入文件名
3、将上面生成的所有文件名之后加上‘_NEW’
4、假设有一个英文文本文件,编写一个程序读取其内容,并将里面的大写字母变成小写字母,小写字母变成大写字母(字符串swapcase方法)
上节答案:
1、一个列表由四个元组组成,每个元组都是四个数字组成,现在要求对这个列表排序排序规则是按照每个元组的第二个元素大小排序
li = [(1,2,3,4),(2,5,8,9),(9,8,7,6),(6,1,4,5)]
li.sort(key = lambda x: x[1])
print(li)
运行结果:
[(6, 1, 4, 5), (1, 2, 3, 4), (2, 5, 8, 9), (9, 8, 7, 6)]
2、实现isPrime()函数,参数是整数,如果整数是质数
返回True,否则返回False
def isPrime(a):
if str(a).isdigit == False:
return Fasle
elif a <= 1:
return False
elif a == 2:
return False
else:
for i in range(2,a):
if a % i == 0:
return False
return True
print(isPrime(4))
print(isPrime(17))
print(isPrime(1))
print(isPrime(-1))
运行结果:
False
True
False
False
3、利用递归函数,实现一个阶乘函数,支持正数和负数的阶乘
def factorial(n):
if n == 0:
return 1
elif n > 0:
return n * factorial(n-1)
else:
return n * factorial(n+1)
print(factorial(-6))
print(factorial(-5))
print(factorial(6))
print(factorial(5))
运行结果:
720
-120
720
120
4、定义一个函数,输入字符串,如果字符串是顺序的则返回‘UP’
如果是倒序的则返回‘DOWN’, 如果是乱序的则返回False
def up_down(x):
if x == ''.join(sorted(x)):
return 'UP'
elif x == ''.join(sorted(x,reverse=True)):
return 'DOWN'
else:
return False
print(up_down('abmcdl'))
print(up_down('abcdef'))
运行结果:
False
UP