[TOC]
1)Python笔试基础知识
- 根据列表、元组和字符串的共同特点,把它们三统称为什么?
序列,因为他们有以下共同点:
- 都可以通过索引得到每一个元素
- 默认索引值总是从0开始(当然灵活的Python还支持负数索引)
- 可以通过分片的方法得到一个范围内的元素的集合
- 有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)
- 你有听说过DRY吗?
DRY是程序员们公认的指导原则:Don’t Repeat Yourself.快快武装你的思维吧,拿起函数不要再去重复拷贝一段代码了!
使用函数:
0) 可以降低代码量(调用函数只需要一行,而拷贝黏贴需要N倍代码)
1) 可以降低维护成本(函数只需修改def部分内容,而拷贝黏贴则需要每一处出现的地方都作修改)
2) 使序更容易阅读(没有人会希望看到一个程序重复一万行“字符串”)
函数参数使用注意?
我们分析下,函数的参数需要的是变量,而这里你试图用“元祖”的形式来传递是不可行的。1
2
3
4
5
6
7#author:WeiyiGeek
def MyFun((x, y), (a, b)): #这种方式是Error 的
return x * y - a * b
#而是采用下面这样的方式进行取值
def myFun(x,a)
return x[0] * x[1] - a[0] * b[1]使用关键字参数,可以有效避免什么问题的出现呢?
关键字参数是指函数在调用的时候,带上参数的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序调用函数,可以有效避免因不小心搞乱参数的顺序导致的BUG出现。
请问Python的return语句可以返回多个不同类型的值吗?
可以丫,默认用逗号隔开,是以元祖的形式返回,你当然也可以用列表包含起来返回:1
2
3
4
5
6
7
8
9def myFun():
return '操chang', 520, 3.14, True
myFun()
('操chang', 520, 3.14, True)
def myFun2():
return ['甲鱼', 1314, 5.12, False]
myFun2()
['甲鱼', 1314, 5.12, False]
>>>建议不到万不得已不要使用全局变量,简洁的概括为?
a) 代码可读性变差
b) 代码安全性降低
以下关于全局变量的危言耸听是转来的,大家不妨也看下:
- 它会造成不必要的常量频繁使用,特别当这个常量没有用宏定义“正名”时,代码阅读起来将万分吃力。
- 它会导致软件分层的不合理,全局变量相当于一条快捷通道,它容易使程序员模糊了“设备层”和“应用层”之间的边界。写出来的底层程序容易自作多情地关注起上层的应用。这在软件系统的构建初期的确效率很高,功能调试进度一日千里,但到了后期往往bug一堆,处处“补丁”,雷区遍布。说是度日如年举步维艰也不为过。
- 由于软件的分层不合理,到了后期维护,哪怕仅是增加修改删除小功能,往往要从上到下掘地三尺地修改,涉及大多数模块,而原有的代码注释却忘了更新修改,这个时候交给后来维护者的系统会越来越像一个“泥潭”,注释的唯一作用只是使泥潭上方再加一些迷烟瘴气。
- 全局变量大量使用,少不了有些变量流连忘返于中断与主回圈程序之间。这个时候如果处理不当,系统的bug就是随机出现的,无规律的,这时候初步显示出病入膏肓的特征来了,没有大牛来力挽狂澜,注定慢性死亡。
- 无需多言如果您的系统中大量使用全局变量,那么您已经成功得到一个畸形的系统,它处于一个神秘的稳定状态!你看着这台机器,机器也看着你,相对无言,心中发毛。你不确定它什么时候会崩溃,也不晓得下一次投诉什么时候道理。
- 在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#!/usr/bin/python3
def fun1():
x = 5
def fun2():
nonlocal x
x *= 2
return x
return fun2 #注意这里没有括号
demo = fun1()
print(demo()) #值不会被释放,留给下次使用
print(demo())
print(demo())
print(demo())
# 其实大家仔细看看就明白了,当 demo = fun1() 的时候,只要 a 变量没有被重新赋值,fun1() 就没有被释放也就是说局部变量 x 就没有被重新初始化。
# 注意return 函数 带与不带()的区别
#方式1:
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn()
#方式2:
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn
#在方式1进行调用 funOut()
宾果!你成功访问到我啦!
#在方式2进行调用 funOut()() 采用访问内嵌函数
宾果!你成功访问到我啦!
#或者采用曲线救国 fun = funOut() 就能通过 fun() 访问内嵌函数
- 使用lambda表达式将下边函数转变为匿名函数?使用匿名函数后给你的编程生活带来的变化?
- 省下定义函数过程,使得代码更加精简;不需要考虑命名的问题了;简化代码的可读性
1
2
3
4
5
6
7
8
9
10
11def fun_A(x, y=3):
return x * y
#转换后的lamdba表达式 (注意参数)
lambda x, y=3 : x * y
#利用filter()和lambda表达式快速求出100以内所有3的倍数
list(filter(lambda n : not(n%3), range(1, 100))) #能整除的时候返回1
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
#列表推导式 ,同样
[ i for i in range(1,100) if not(i % 3)]
- 按照递归的特性,在编程中有没有不得不使用递归的情况?
答:例如汉诺塔,目录索引(因为你永远不知道这个目录里边是否还有目录),快速排序(二十世纪十大算法之一),树结构的定义等如果使用递归,会事半功倍,否则会导致程序无法实现或相当难以理解。
- 字典Dict知识点回顾。
字典:在Pythgon中叫“映射”、“哈希”、“散列”或者“关系数组”等等
Python 调用内部的散列函数,将键(Key)作为参数进行转换,得到一个唯一的地址(这也就解释了为什么给相同的键赋值会直接覆盖的原因,因为相同的键转换后的地址是一样滴),然后将值(Value)存放到该地址中;对于 Python 来说,键(Key)必须是可哈希的,换句话说就是要可以通过散列函数计算出唯一地址的。
那如果拿一个变量当键(Key)可以吗?
肯定不行,因为变量随时都可能改变,不符合可哈希原则!
那有朋友可能会问,元祖总该是不变的吧?
其实不然,因为元祖里边可以存放列表这类可变因素,所以如果实在想拿元祖当字典的键(Key),那必须对元祖做限制:元组中只包括像数字和字符串这样的不可变元素时,才可以作为字典中有效的键(Key)。
注意:Python 的哈希算法对相同的值计算得到的结果是一样的,比 12315 和 12315.0 的值相同,他们被认为是相同的键(Key)。1
2
3
4
5
6
7
8
9
10
11
12
131, two=2, three=3) a = dict(one=
'one': 1, 'two': 2, 'three': 3} b = {
'one', 'two', 'three'], [1, 2, 3])) c = dict(zip([
'two', 2), ('one', 1), ('three', 3)]) d = dict([(
'three': 3, 'one': 1, 'two': 2}) e = dict({
# 字典可以这样赋值
my = {}
'id'],my['name']) = (1024,'Weiyigeek') (my[
'id'],my['name']) = "1000,甲鱼".split(',') (my[
# 字典dict1的内容
1, 3), '数字') #答:执行完成后,字典dict1的内容是:{1: '数字', 3: '数字'} dict1.fromkeys((
- 集合set知识点回顾?
- 集合几乎所有的作用就是确保里边包含的元素的唯一性,集合内不可能存在两个相同的元素!
- 注意集合是无序的,不能采用索引的num_set[0]和切片的num_set[:]方式进行
- set1 = set([1, 2]) 会生成一个集合{1, 2},但set1 = {[1, 2]}却会报错,由于集合跟字典的存储方式一样的丫!(“列表不是可哈希类型”),且认为 1 == 1.0 是等值的所以set1 = {1,1.0}
- 文件操作知识点回顾?
- Windows在路径名中既可以接受斜线(/)也可以接受反斜线(\),不过如果使用反斜线作为路径名的分隔符的话,要注意使用双反斜线(\)
1
2
3
4f = open('E:/test.txt', 'w') # A
f = open('E:\\test.txt', 'w') # C
f = open('E:\\Test.bin', 'xb')
#注意的是'x'和'w'均是以“可写入”的模式打开文件,但以'x'模式打开的时候,如果路径下已经存在相同的文件名,会抛出异常,而'w'模式的话会直接覆盖同名文件(比较危险)。 - open()函数默认的打开模式是’rt’(即可读、文本的模式打开)
- Python可能会缓存你写入的数据,如果这中间断电了神马的,那些缓存的数据根本就不会写入到文件中,所以建议是哟个 f.close() 将缓存数据写入并关闭文件
- 将一个文件对象(f)中的数据存放进列表 , 直接list(f)。
- 在进行截取和偏移的时候,需要注意打开文件的编码格式,如以GBK编码则(一个汉字需要占用两个字节),所以需要*2进行截取。
常见异常情况?
1
2
3
4
5
6
7
8
9
10
11
121, 2, 3, 4,,] #SyntaxError: invalid syntax my_list = [
1, 2, 3, 4, 5] my_list = [
#试图访问 my_list(5) 会引发 IndexError: list index out of range 异常。 print(my_list[len(my_list)])
#AttributeError: 'list' object has no attribute 'sorted' my_list.sorted()
'host': 'http://bbs.fishc.com', 'port': '80'} my_dict = {
'server']) #不存在的“键”引发 KeyError: 'server' 异常 print(my_dict[
f = open('C:\\test.txt', wb) #注意 open() 第二个参数是字符串 否则引发 NameError 异常
f.write('I love FishC.com!\n')
f.close()except 后边如果不带任何异常类,Python 会捕获所有(try 语句块内)的异常并统一处理,但却不建议这么做,你知道为什么吗?
答:因为它会隐藏所有程序员未想到并且未做好准备处理的错误,例如:用户输入ctrl+c试图终止程序会被解释为KeyboardInterrupt异常。
使用 with 语句相当方便,with 语句会自动处理文件的打开和关闭(with open(‘data.txt’, ‘w’) as f),如果中途出现异常会执行清理代码,然后确保文件自动关闭。
2)Python操作实验
- min() 这个BIF的实现过程还原? sum()BIF有个缺陷,就是如果参数里有字符串类型的话就会报错,写出一个新的实现过程自动“无视”参数里的字符串并返回正确的计算结果?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#!/usr/bin/python3
# min 内置函数的实现 与 sum bug 解决
#author:WeiyiGeek
def min(x):
initvalue = x[0]
for each in x:
if each < initvalue: #实际采用的ASCII进行比对的
initvalue = each
else:
print("计算成功")
return initvalue
def sum(x):
result = 0
for each in x:
if isinstance(each,int) or isinstance(each,float):
result += each
return result;
print("min",min('178546810'))
print("sum",sum([1,3,6.6,'y',"abcd"]))
##### 计算成功结果 ######
# min = 0
# sum = 10.6
编写一个函数 findstr(),该函数统计一个长度为 2 的子字符串在另一个字符串中出现的次数。例如:假定输入的字符串为“You cannot improve your past, but you can improve your future. Once time is wasted, life is wasted.”,子字符串为“im”,函数执行后打印“子字母串在目标字符串中共出现 3 次”。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#author:WeiyiGeek
#方法1:count()方法
def findstr1():
string = "You cannot improve your past, but you can improve your future. Once time is wasted, life is wasted."
temp = input("请输入字符串:")
if temp.isspace() or len(temp) <= 2:
temp = string
temp1 = input("输入查找的字符串(两个以上):")
while len(temp1) < 2:
temp1 = input("查找字符长度有误,请重新输入:")
print(temp.count(temp1))
findstr1()
#方法2:
def findStr(desStr, subStr):
count = 0
length = len(desStr)
if subStr not in desStr:
print('在目标字符串中未找到字符串!')
else:
for each1 in range(length-1):
if desStr[each1] == subStr[0]: #主要代码在这里判断连续的两个字符是不相等
if desStr[each1+1] == subStr[1]:
count += 1
print('子字符串在目标字符串中共出现 %d 次' % count)
desStr = input('请输入目标字符串:')
subStr = input('请输入子字符串(两个字符):')
findStr(desStr, subStr)
########## 输出结果 ###############
# 请输入字符串:tesadasdsadasdasdasdasdasd
# 输入查找的字符串(两个以上):as
# 6编写一个函数,判断传入的字符串参数是否为“回文联”(回文联即用回文形式写成的对联,既可顺读,也可倒读。例如:上海自来水来自海上)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49def palindrome(string):
length = len(string)
last = length-1
length //= 2
flag = 1
for each in range(length):
if string[each] != string[last]:
flag = 0
last -= 1
if flag == 1:
return 1
else:
return 0
string = input('请输入一句话:')
if palindrome(string) == 1:
print('是回文联!')
else:
print('不是回文联!')
#方法2:
def palindrome(string):
list1 = list(string)
list2 = reversed(list1)
if list1 == list(list2):
return '是回文联!'
else:
return '不是回文联!'
print(palindrome('上海自来水来自海上'))
#方法3:递归方式
def is_palindrome(n, start, end):
if start > end:
return 1
else:
return is_palindrome(n, start+1, end-1) if n[start] == n[end] else 0
string = input('请输入一串字符串:')
length = len(string)-1
if is_palindrome(string, 0, length):
print('"%s"是回文字符串!' % string)
else:
print('"%s"不是回文字符串!' % string)
#请输入一段话:上海自来水来自海上
#回文数
编写一个函数,分别统计出传入字符串参数(可能不只一个参数)的英文字母、空格、数字和其它字符的个数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#!/usr/bin/python
#author:WeiyiGeek
def count(*param):
length = len(param)
for i in range(length):
letters = 0
space = 0
digit = 0
others = 0
for each in param[i]: #区别是第几个字符串
if each.isalpha(): #用得很好
letters += 1
elif each.isdigit():
digit += 1
elif each == ' ':
space += 1
else:
others += 1
print('第 %d 个字符串共有:英文字母 %d 个,数字 %d 个,空格 %d 个,其他字符 %d 个。' % (i+1, letters, digit, space, others))
count('I love weiyigeek.github.io.', 'I love you, you love me.')
####################### 输出结果 ################################
# 第 1 个字符串共有:英文字母 18 个,数字 0 个,空格 2 个,其他字符 2 个。
# 第 2 个字符串共有:英文字母 17 个,数字 0 个,空格 5 个,其他字符 2 个。
# 请按任意键继续. . .游戏中的角色移动:闭包(closure)在实际开发中的作用?
在某种情况下,我们并不方便使用全局变量,所以灵活的使用闭包可以实现替代全局变量。
在游戏开发中,我们需要将游戏中角色的移动位置保护起来,不希望被其他函数轻易可以修改到,所以我们选择使用闭包操作,参考代码及注释如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34# -*- coding: utf8 -*-
origin = (0,0)
legalx = [-100,100]
legaly = [-100,100]
def create(posx=0,posy=0):
def moving(direction,step):
# direction参数设置方向,1为向右(向上),-1为向左(向下),0为不移动
# step参数设置移动的距离
nonlocal posx,posy
newx = posx + direction[0] * step
newy = posy + direction[1] * step
# 检查移动后是否能够超出X轴边界
if newx<legalx[0]:
posx = legalx - (newx - legalx) # -100 - (-101 + 100) => -100 + 1 ==> -99
elif newx > legalx[1]:
posx = legalx[1] - (newx - legalx[1]) # 100 - (101 - 100) => 99
else:
posx = newx
#注意这里,会返回到下一次的调用之中
# 检查移动后是否超出y轴边界
if newy < legaly[0]:
posy = legaly - (newy - legaly)
elif newy > legaly[1]:
posy = legaly[1] - (newy - legaly[1])
else:
posy = newy
return posx,posy
return moving
move = create()
print('向右移动10步后,位置是:', move([1, 0], 10))
print('向上移动130步后,位置是:', move([0, 1], 130))
print('向左移动10步后,位置是:', move([-1, 0], 10))注意:的一点是:move = create(),如果当 move 变量重新被赋值的话,相应的 pos_x 和 pos_y 也都会被初始化为 0。
- 请用已学过的知识编写程序,统计下边这个长字符串中各个字符出现的次数.
1
2
3
4
5
6
7
8
9str1 = '''拷贝过来的字符串'''
list1 = []
for each in str1:
if each not in list1: #如果不在 list1 中,执行统计
if each == '\n':
print('\\n', str1.count(each))
else:
print(each, str1.count(each)) #使用比较精辟
list1.append(each)
使用递归算法求解下面二的问题
Q:有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?
解题思路:利用递归的方法,递归分为回推和递推两个阶段。要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。1
2
3
4
5
6
7
8#!/usr/bin/python
def age(n):
if n == 1:
return 10
else:
return age(n-1)+2
print('哈哈,我知道了,第五个人的年龄是 %d 岁,啵啵脆!' % age(5))采用字典写出通讯录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
print('|--- 欢迎进入通讯录程序 ---|')
print('|--- 1:查询联系人资料 ---|')
print('|--- 2:插入新的联系人 ---|')
print('|--- 3:删除已有联系人 ---|')
print('|--- 4:退出通讯录程序 ---|')
contacts = dict()
while 1:
instr = int(input('\n请输入相关的指令代码:'))
if instr == 1:
name = input('请输入联系人姓名:')
if name in contacts:
print(name + ' : ' + contacts[name])
else:
print('您输入的姓名不再通讯录中!')
if instr == 2:
name = input('请输入联系人姓名:')
if name in contacts:
print('您输入的姓名在通讯录中已存在 -->> ', end='')
print(name + ' : ' + contacts[name])
if input('是否修改用户资料(YES/NO):') == 'YES':
contacts[name] = input('请输入用户联系电话:')
else:
contacts[name] = input('请输入用户联系电话:')
if instr == 3:
name = input('请输入联系人姓名:')
if name in contacts:
del(contacts[name]) # 也可以使用dict.pop()
else:
print('您输入的联系人不存在。')
if instr == 4:
break
print('|--- 感谢使用通讯录程序 ---|')
- 用函数模块的形式进行封装用户登陆注册模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71#!/usr/bin/python3
# 功能:登陆login/register
user_data = {}
'提示'
def tip():
print("###### 新建用户:N/n ######")
print("###### 登陆用户:E/e ######")
print("###### 登陆用户:Q/q ######")
'注册模块'
def reg():
name = input("请输入注册名用户名")
while True:
if name in user_data:
name = input("用户名已被占用,请重新输入:")
else:
break
password = input("请输入密码:")
user_data.setdefault(name, password)
print("Ok.注册成功")
'登陆模块'
def login():
name = input("请输入登陆的账户:")
while True:
if name not in user_data:
name = input("输入的用户名不存在,请重新输入用户名:")
else:
break
password = input("请输入密码:")
if user_data[name] == password:
print("Ok.登陆成功")
else:
print("Error.密码错误")
'主模块'
def user():
tip()
while 1:
temp = input("|---请输入指令代码:")
if temp.lower() == 'n':
reg()
if temp.lower() == 'e':
login()
if temp.lower() == 'q':
break
print("退出成功,欢迎下次使用!")
user() #调用主模块
################# 结果输出 ###############
###### 新建用户:N/n ######
###### 登陆用户:E/e ######
###### 登陆用户:Q/q ######
# |---请输入指令代码:N
# 请输入注册名用户名weiyigeek
# 请输入密码:5
# Ok.注册成功
# |---请输入指令代码:e
# 请输入登陆的账户:weiyigeek
# 请输入密码:5
# Ok.登陆成功
# |---请输入指令代码:q
# 退出成功,欢迎下次使用!
文件操作案例(1),指定字符输入完毕后写入文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#!/usr/bin/python3
#文件操作
#方式1
filename = input("请输入一个文件名:")
f = open(filename,'x',encoding='utf-8')
list1 = []
print(r'"请输入内容,单独输入\':w\'保存:"')
while True:
value = input()
if value != ":w":
list1.append(value+'\n')
else:
f.writelines(list1) #注意这里是直接使用 writelines 将列表值暂时写入到文件中
break
f.close() #关闭文件
#方法2:
while True:
write_some = input()
if write_some != ':w':
f.write('%s\n' % write_some) # write 不能直接将列表值写入到文件中 需要进行循环写入
else:
break
################# 结果输出 ###############
# 请输入一个文件名:test.txx
# "请输入内容,单独输入\':w\'保存:"
# test
# Pyton
# asdsa
# 123546678
# :w用户可以随意输入需要显示的行数。(如输入13:21打印第13行到第21行,输入:21打印前21行,输入21:则打印从第21行开始到文件结尾所有内容)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43def file_view(file_name, line_num):
if line_num.strip() == ':':
begin = '1'
end = '-1'
(begin, end) = line_num.split(':')
if begin == '':
begin = '1'
if end == '':
end = '-1'
if begin == '1' and end == '-1':
prompt = '的全文'
elif begin == '1':
prompt = '从开始到%s' % end
elif end == '-1':
prompt = '从%s到结束' % begin
else:
prompt = '从第%s行到第%s行' % (begin, end)
print('\n文件%s%s的内容如下:\n' % (file_name, prompt))
begin = int(begin) - 1
end = int(end)
lines = end - begin
f = open(file_name)
for i in range(begin): # 用于消耗掉begin之前的内容
f.readline()
if lines < 0:
print(f.read())
else:
for j in range(lines):
print(f.readline(), end='')
f.close()
file_name = input(r'请输入要打开的文件(C:\\test.txt):')
line_num = input('请输入需要显示的行数【格式如 13:21 或 :21 或 21: 或 : 】:')
file_view(file_name, line_num)打开文件操作使用案例
- os模块使用案例文件统计搜寻及文件扩展名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68#!/usr/bin/python3
#OS模块的使用
import os
all_files = os.listdir(os.curdir) # 使用os.curdir表示当前目录更标准 | 显示当前目录与文件
type_dict = dict() #类型
file_dict = dict() #文件及大小
for each_file in all_files:
if os.path.isdir(each_file):
type_dict.setdefault('文件夹', 0)
type_dict['文件夹'] += 1
else:
#扩展名文件统计
ext = os.path.splitext(each_file)[1]
type_dict.setdefault(ext, 0) #注意 当字典里面不存在的时候才会建立赋值为0 , 否则不对字典里面key/VALUE值进行操作
type_dict[ext] += 1 #直接进行字典value运算
#文件大小统计
file_dict.setdefault(each_file,os.path.getsize(each_file))
#统计文件类型格式
for each_type in type_dict.keys():
print('该文件夹下共有类型为【%s】的文件 %d 个' % (each_type, type_dict[each_type]))
#显示文件及其大小
for each_size in file_dict.items():
print("fileName:%s , Size: %dBytes" %(each_size[0],each_size[1]))
vedio_list = []
#用户输入文件名以及开始搜索的路径
def search_file(start_dir, target) :
os.chdir(start_dir) #进入目录
for each_file in os.listdir(os.curdir) :
if each_file == target :
print(os.getcwd() + os.sep + each_file) # 使用os.sep是程序更标准
break
if os.path.isdir(each_file) :
search_file(each_file, target) # 递归调用
os.chdir(os.pardir) # 递归调用后切记返回上一层目录
print("搜寻到文件:")
search_file(os.curdir,'homework1.py')
#按照扩展名进行搜寻
# targetext = ['avi','txt','py']
# if ext in targetext :
# vedio_list.append(os.getcwd() + os.sep + each_file + os.linesep) # 使用os.sep是程序更标准
################ 执行案例 ###################
# 该文件夹下共有类型为【文件夹】的文件 3 个
# 该文件夹下共有类型为【.py】的文件 5 个
# fileName:demo3.0.py , Size: 1528Bytes
# fileName:demo3.1.py , Size: 1062Bytes
# fileName:demo3.2.py , Size: 1319Bytes
# fileName:demo3.3.py , Size: 1850Bytes
# fileName:homework1.py , Size: 1677Bytes
# 搜寻到文件:
# C:\Users\Administrator\Desktop\Python\1\homework1.py
# C:\Users\Administrator\Desktop\Python\2\homework1.py
# C:\Users\Administrator\Desktop\Python\homework1.py
- 用户输入关键字,查找当前文件夹内(如果当前文件夹内包含文件夹,则进入文件夹继续搜索)所有含有该关键字的文本文件(.txt后缀),要求显示该文件所在的位置以及关键字在文件中的具体位置(第几行第几个字符)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56import os
def print_pos(key_dict):
keys = key_dict.keys()
keys = sorted(keys) # 由于字典是无序的,我们这里对行数进行排序
for each_key in keys:
print('关键字出现在第 %s 行,第 %s 个位置。' % (each_key, str(key_dict[each_key])))
def pos_in_line(line, key):
pos = []
begin = line.find(key)
while begin != -1:
pos.append(begin + 1) # 用户的角度是从1开始数
begin = line.find(key, begin+1) # 从下一个位置继续查找
return pos
def search_in_file(file_name, key):
f = open(file_name)
count = 0 # 记录行数
key_dict = dict() # 字典,用户存放key所在具体行数对应具体位置
for each_line in f:
count += 1
if key in each_line:
pos = pos_in_line(each_line, key) # key在每行对应的位置
key_dict[count] = pos
f.close()
return key_dict
def search_files(key, detail):
all_files = os.walk(os.getcwd())
txt_files = []
for i in all_files:
for each_file in i[2]:
if os.path.splitext(each_file)[1] == '.txt': # 根据后缀判断是否文本文件
each_file = os.path.join(i[0], each_file)
txt_files.append(each_file)
for each_txt_file in txt_files:
key_dict = search_in_file(each_txt_file, key)
if key_dict:
print('================================================================')
print('在文件【%s】中找到关键字【%s】' % (each_txt_file, key))
if detail in ['YES', 'Yes', 'yes']:
print_pos(key_dict)
key = input('请将该脚本放于待查找的文件夹内,请输入关键字:')
detail = input('请问是否需要打印关键字【%s】在文件中的具体位置(YES/NO):' % key)
search_files(key, detail)Weiyigeek.os.path使用
- try except 文件打开异常案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14#!/usr/bin/python3
#功能:课后作业
try:
f = open('My_File.txt') # 当前文件夹中并不存在"My_File.txt"这个文件T_T (而且是一个局部变量)
print(f.read())
except OSError as reason:
print('出错啦:' + str(reason))
finally:
if 'f' in locals(): # 如果文件对象变量存在当前局部变量符号表的话,说明打开成功
f.close()
##################### 结果 ################################
#出错啦:[Errno 2] No such file or directory: 'My_File.txt'
#请按任意键继续. . .
- 目录中所有文件的行数统计?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24!/usr/bin/python3
功能:代码行数统计
import os
count = 0 # 代码行数
def filecount(dirpath):
global count
os.chdir(dirpath)
for each_file in os.listdir(os.curdir):
if os.path.isfile(each_file):
with open(each_file,'r',encoding='utf8') as f:
for index,value in enumerate(f):
count += 1
elif os.path.isdir(each_file):
filecount(each_file)
os.chdir(os.pardir)
filecount('C:\\Users\\Administrator\\Desktop\\JAVA-Study')
print("当前目录中一共写了%d 行代码" %count)
################执行结果########################
C:\Users\Administrator\Desktop\Python>python codecount.py
当前目录中一共写了112 行代码