python基础知识点补充

学习中碰到就会记录补充

1.在使用幂运算时,幂运算大于左边的单目操作符小于右边的(eg:负号)
2.python3中,除法默认是会算出小数,要想用取整的除法利用//
3.判断变量类型有type()和isinstance(变量,类型)后者较为好用
4 print(,end=“”)来改变结尾是换行符
5.float-》int默认是截断而不是四舍五入,可以利用+0.5来实现
6.关于逻辑and和or,python的用法和C的用法主要异同点如下:
(1)、当两个操作数均为逻辑值时,与我们通常理解的逻辑运算一致;
(2)、当第一个操作数为逻辑值,第二个操作数为其他类型时,执行以下规则:
a and b:在a为false的时候,返回a,否则返回b。
a or b: 在a为true的时候,返回a,否则返回b。
总之,and与or返回的不仅有true/false的语义,还返回了它的值。
7.非0为True,0False
8.input读取的是字符串,利用bif内置函数来转换变量类型
9.变量先赋值在使用
10.为什么python print((2 ** 2) ** 32)可以输出,print(2 ** 2**32)不能:由于幂运算是 从右往左 运算的,所以 print(2 ** 2 ** 32) 就相当于 print(2 ** 4294967296),数字太大了,Python 一时算不出结果。

而 print((2 ** 2) ** 32) 加了括号,相当于 print(4 ** 32),Python 当然可以很快算出是 18446744073709551616。
11.not or and 的优先级是不同的:not > and > or
12.假设有 x = 1,y = 2,z = 3,请问如何快速将三个变量的值互相交换?
x, y, z = z, y, x

x, y, z = 6, 5, 4
      if x < y:
    small = x
    if z < small:
        small = z
elif y < z:
    small = y
else:
    small = z`等价于`small = x if (x < y and x < z) else (y if y < z else z)`

14.游戏实现,操作系统一般要用永真循坏,因为游戏只要运行着,就需要时刻接收用户输入,因此使用永远为真确保游戏“在线”。操作系统也是同样的道理,时刻待命,操作系统永远为真的这个循环叫做消息循环。另外,许多通讯服务器的客户端/服务器系统也是通过这样的原理来工作的。
15.append只能每次往列表添加一个元素(这个元素可以是列表),而extend方法是用一个列表去扩充另一个列表(entend中的列表里的元素全部加入到被扩充的列表中);两者都是尾部;insert是选定位置插入----(增加列表方法append extend insert)

name = ['F', 'i', 's', 'h']
name.append('C')
>>> name
['F', 'i', 's', 'h', 'C']
 name.extend(['.', 'c'])
>>> name
['F', 'i', 's', 'h', 'C', '.', 'c']
name.append(['o', 'm'])
>>> name
['F', 'i', 's', 'h', 'C', '.', 'c', ['o', 'm']]

16,列表的具体元素访问类似c数组访问,x[下标]
17.列表删除:remove(列表名.remove(所删元素)),del(del 列表名[下标] or del 列表名),pop(删除列表最后一个,并返回给你,也可以加索引值来弹出给定的下标对应的元素)
18.列表的切片,和range函数都是包含第一个参数,不包含第二个参数,即[0:3]->0 1 2 (0,3)->0,1,2
19. list1[0] 和 list1[0:1] 不一样,list1[0] 返回第0个元素的值,list1[0:1] 返回一个只含有第0个元素的列表
20. 列表正索引由左到右,负索引由右到左;
21. 分片完成列表的拷贝 list2 = list1[:],不可以直接写成 list2 = list1 ,此时list2和list1指向相同,所以对1改也是对2改, list2 = list1[:]则两个链表各是各的,指向不同
22. in,not in 只作用在列表的一层(列表里面有列表属于多层)类似break continue
23. 列表的元素可以任意修改,删除,加入,元组不能任意的插入或删除元素,元组是不可改变的-封闭的列表,一旦定义,就不可改变(不能添加、删除或修改)
24. 创建只有一个元素的元组(1)这样不对,而且查看是int型,正确的为(1,)/1, 空元组 ()
25. 所有的多对象的、逗号分隔的、没有明确用符号定义的这些集合默认的类型都是元组 eg: x, y, z = 1, 2, 3,x, y, z是元组
26. 汉字字符串利用islower方法时得到的也是false因为不在26个字母中
27. 字符串类似元组生成之后无法再修改,只能通过拼接或方法调用等再贴上新的标签来改变,(字符串的方法类似lstrip,join不改变其本身,类似于得到新的字符串)
28. 三引号字符串通常用来做跨行注释使用。
29. 请写一个密码安全性检查的代码:
解释:(1). 为啥要用 while 1 呢?主要是为了实现“如果结果是低或中则打印如何提升密码安全级别的提示,而高则直接退出”(2). 为啥把“高”放中间呢?因为其判断最为麻烦(注意还要求必须是字母开头),所以很有可能满足了“中”却因为额外的条件满足不了“高”,因此我们把事儿比较多的高放中间判断,满足不了“高”,那就只能是最后的 else“中”了。

# 密码安全性检查代码
    #
    # 低级密码要求:
    #   1. 密码由单纯的数字或字母组成
    #   2. 密码长度小于等于8位
    #
    # 中级密码要求:
    #   1. 密码必须由数字、字母或特殊字符(仅限:~!@#$%^&*()_=-/,.?<>;:[]{}|\)任意两种组合
    #   2. 密码长度不能低于8位
    #
    # 高级密码要求:
    #   1. 密码必须由数字、字母及特殊字符(仅限:~!@#$%^&*()_=-/,.?<>;:[]{}|\)三种组合
    #   2. 密码只能由字母开头
    #   3. 密码长度不能低于16位

    symbols = r'''`!@#$%^&*()_+-=/*{}[]\|'";:/?,.<>'''
    chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    nums = '0123456789'

    passwd = input('请输入需要检查的密码组合:')

    # 判断长度
    length = len(passwd)

    while (passwd.isspace() or length == 0) :
        passwd = input("您输入的密码为空(或空格),请重新输入:")
        length = len(passwd)

    if length <= 8:
        flag_len = 1
    elif 8 < length < 16:
        flag_len = 2
    else:
        flag_len = 3

    flag_con = 0

    # 判断是否包含特殊字符
    for each in passwd:
        if each in symbols:
            flag_con += 1
            break
       
    # 判断是否包含字母
    for each in passwd:
        if each in chars:
            flag_con += 1
            break

    # 判断是否包含数字
    for each in passwd:
        if each in nums:
            flag_con += 1
            break   

    # 打印结果
    while 1 :
        print("您的密码安全级别评定为:", end='')
        if flag_len == 1 or flag_con == 1 :
            print("低")
        elif flag_len == 3 and flag_con == 3 and (passwd[0] in chars):
            print("高")
            print("请继续保持")
            break
        else:
            print("中")

        print("请按以下方式提升您的密码安全级别:\n\
        \t1. 密码必须由数字、字母及特殊字符三种组合\n\
        \t2. 密码只能由字母开头\n\
        \t3. 密码长度不能低于16位")
        break

30.使用max,min方法要保证序列or参数的数据类型是统一的(都是字符,数字等,不能混杂会报错)
31. enmerate,reversed返回的都是迭代器(目前可用list(reversed(**))+print显示)
32. 进制转换:

`while 1:
    s=input("请输入一个整数(按Q结束程序):")
    if(s=='Q') :
        break
    else:
        s=int(s)
        print("十进制转十六进制:",end=" " )
        print("%d-> 0x%x" %(s,s))
        print("十进制转八进制:", end=" ")
        print("%d-> 0o%x" % (s, s))
        print("十进制转二进制:", end=" ")
        print('%d ->'%s,bin(s))`

33.sum() 这个BIF有个缺陷,就是如果参数里有字符串类型的话就会报错,请写出一个新的实现过程,自动“无视”参数里的字符串并返回正确的计算结果

sum=0
for i in list1:
    if  isinstance(i,int) or isinstance(i,float):
        sum+=i
    else :
        continue
print(sum)

34.这个函数有多少个参数

def MyFun((x, y), (a, b)):
    return x * y - a * b

两个是错的答案是0,因为类似于这样的写法是错误的!
我们分析下,函数的参数需要的是变量,而这里你试图用“元祖”的形式来传递是不可行的。
正确写法:

 def MyFun(x, y):
      return x[0] * x[1] - y[0] * y[1]

 MyFun((3, 4), (1, 2))

35.收集参数是用元组打包起来的,在收集参数后还想定制参数,需要使用关键字参数,不然会默认为收集参数(所以一般建议为设置为默认参数,即使没有写,也会有初值)
36.默认参数是在定义函数的时候写,关键字参数是用来告诉函数哪一个是对应的参数,所以是在函数调用的时候写 parameter=x
37.编写一个函数 findstr(),该函数统计一个长度为 2 的子字符串在另一个字符串中出现的次数。例如:假定输入的字符串为“You cannot improve your past, but you can improve your future. Once time is wasted, life is wasted.”,子字符串为“im”,函数执行后打印“子字母串在目标字符串中共出现 3 次”。

def findStr(desStr, subStr):
    count = 0
    length = len(desStr)
    if subStr not in desStr:
        print('在目标字符串中未找到字符串!')
    else:
        for each1 in range(length-1): #用length-1,是因为实际each1到了length-2即可,     
            if desStr[each1] == subStr[0]:
                if desStr[each1+1] == subStr[1]:
                    count += 1
                    
        print('子字符串在目标字符串中共出现 %d 次' % count)

desStr = input('请输入目标字符串:')
subStr = input('请输入子字符串(两个字符):')
findStr(desStr, subStr)

36.回文判断:

def huiwen(string):
      list1=list(string)
      list2=reversed(list1)
      if list1==list(list2):
          return '是回文'
      else:
          return '不是回文'

37:允许函数内部定义函数
38.辨析:
对的代码:

def outside():
    var=5
    def inside():
        var=3
        print(var)
    inside()
outside()

错误:

def outside():
    var=5
    def inside():
        print(var)
        var=3
    inside()
outside()

第二个出错,报错内容:UnboundLocalError: local variable ‘var’ referenced before assignment
因为:outside()函数里有一个var变量,但要注意,内嵌函数inside()也有一个var变量,python保护变量作用域,故将outside()中的var变量屏蔽起来,所以此时无法访问到外层var变量;可利用nonlocal 来访问非全局作用域的外部作用域的局部变量
40.如何访问funin():

def funout():
    def funin():
        print("bingo,you have accessed into the in")
    return funin()
funout()

如何访问funin()

def funout():
    def funin():
        print("bingo,you have accessed into the in")
    return funin
funout()()
'''or go=funout()
go()'''

41.filter和lambda组合求出一百以内三的倍数:

print(list(filter(lambda x:not(x%3),range(1,100))))
#filter只有两个参数,函数(可没有,或者是从后者每一个元素进行计算中筛选正确的,并返回),可迭代的对象

42.利用map和lambda返回类似[[1,2],[3,4],[5,6],[7,8]]:

list(map(lambda x,y:[x,y],[1,3,5,7,9],[2,4,6,8,10]))
#map()后面可接受多个序列作为参数

43.利用递归写出十进制转换二进制:

def zhuanhuan(n):
    result=''
    if n:
        result=zhuanhuan(n//2)
        return result+str(n%2)
    else:
        return result
print(zhuanhuan(62))

44.利用递归来判断回文:

#利用递归每次索引前后两个字符进行对比,当start>end,正是首尾下标碰面时,作为结束递归的条件
def huiwen(n,start,end):
    if start>end:
        return 1#能到这说明之前的都成立了
    else:
        return huiwen(n,start+1,end-1) if n[start]==n[end] else 0#如果不相等直接为0退出
string=input("please input the string:")
length=len(string)-1
if(huiwen(string,0,length)):
    print("\%s\是回文" %string )
else:
    print("\%s\不是回文" % string)

45.字典创建方式:
(用大括号)

1.dict2={1:'one',2:'two',3:'three'}
2.dict3=dict([('f',70),('i',105),('s',115),('h',104),('c',67)])
3.dict3=dict((('f',70),('i',105),('s',115),('h',104),('c',67)))
因为dict()只能有一个参数,所用元组或列表包围形成一个参数
4.dict4=dict(charles="sdhaskj",shou='sdsdsd')#用关键字来创建,key值不用加引号
5.利用fromkeys,Python 字典 fromkeys() 函数用于创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值
dict.fromkeys(seq[, value]):seq -- 字典键值列表。 value -- 可选参数, 设置键序列(seq)的值。不写默认value为none

46.字典查找的元素的键而不是值,序列查找元素的值,而不是元素的索引号
47.赋值只是在对同一个数据贴了不同的标签,而浅拷贝是对对象的表层拷贝
48.字典的编排没有顺序,所以popitem可以理解为随即弹出数据,而pop是给定key,把字典中key和对应的value从字典中弹出
49:简易电话簿:


print("|---欢迎进入通讯录程序---|")
print("|--- 1:查询联系人资料 ---|")
print("|--- 2:插入新的联系人 ---|")
print("|--- 3:删除已有联系人 ---|")
print("|--- 4:推出通讯录程序 ---|")
dict1={}
while 1:
    temp=int(input("请输入相关的指令代码:"))
    if temp == 1:
        x=input("请输入联系人姓名:")
        if x in dict1:
          print(x," : ",dict1[x])
        else:
            print("您输入的姓名不在通讯录中!")
        continue
    if temp == 4:
        print("|--- 感谢使用通讯录程序 ---|")
        break
    if temp == 2:
        x=input("请输入联系人姓名:")
        if(dict1.get(x)==None):
            y=input("请输入用户联系电话:")
            dict1[x]=y
            continue
        else:
            print("您输入的姓名在通讯录中已存在-->>",x," : ",dict1[x])
            judge=input("是否需要修改用户资料YES/NO:")
            if(judge=='YES'):
                z = input("请输入用户联系电话:")
                dict1[x] = z
            continue
    if temp == 3:
        x=input("请输入联系人姓名:")
        if x in dict1:
          dict1.pop(x)
          print("删除成功!")
        else:
            print("您输入的姓名不在通讯录中!")
        continue
---------------------------------------------------
#因为每次访问字典的键效率较低,所以我们利用异常解决方案,简单避开每次使用in判断键存在字典的操作因为只要
#当键不存在字典中时,会触发keyerror异常,所以我们对代码修改如下:
print("|---欢迎进入通讯录程序---|")
print("|--- 1:查询联系人资料 ---|")
print("|--- 2:插入新的联系人 ---|")
print("|--- 3:删除已有联系人 ---|")
print("|--- 4:推出通讯录程序 ---|")
contacts=dict()
while 1:
    temp=int(input("\n请输入相关的指令代码:"))
    if temp == 1:
        name=input("请输入联系人姓名:")
        try:
            print(name+":"+contacts[name])
        except KeyError:
            print("您输入的名字不在通讯录中")
    if temp == 4:
        print("|--- 感谢使用通讯录程序 ---|")
        break
    if temp == 2:
        name=input("请输入联系人姓名:")
        try:
            print(name+':'+contacts[name])
            print("您输入的姓名在通讯录中已存在",end='')
            if input('是否修改用户资料Yes/No')=='Yes':
                contacts[name]=input('请输入用户联系电话:')
        except KeyError:
            contacts[name] = input('请输入用户联系电话:')
    if temp == 3:
       name=input("请输入联系人姓名:")
       try:
           del(contacts[name])
       except KeyError:
           print("您输入的联系人不存在。")

50.用大括号括起来的不只是字典还有集合
51.利用in 检查元素是否在序列中效率没有在字典中检查键高,因为字典利用hash算法一步到位,不需要查找算法匹配,时间复杂度o(1)
52.字典对键的要求相对严格,必须是可哈希的对象,不能是可变类型(包括变量,列表,字典本身等),对值没有任何限制
53.简易用户登录程序,将功能封装成函数:

userdata={}
def new():
    prompt='请输入用户名:'
    while True:#控制来得到正确的未被用过的名字
        name=input(prompt)
        if name in userdata:
            prompt='此用户名已经被使用,请重新输入:'
            continue
        else:
            break
    passwd=input("请输入密码:")
    userdata[name]=passwd
    print("注册成功,赶紧试试登录吧")

def old():
    prompt = '请输入用户名:'
    while True:#控制来得到正确的注册过的名字
        name=input(prompt)
        if name not in userdata:
            prompt='您输入的用户名不存在,请重新输入:'
            continue
        else:
            break
    passwd=input("请输入密码:")
    pwd=userdata.get(name)
    if passwd==pwd:
        print("欢迎进入系统,请点击右上角的x结束程序!")
    else:
        print("密码错误!")
def showmenu():
    prompt='''
|--- 新建用户:N/n ---|
|--- 登录账号:E/e ---|
|--- 退出程序:Q/q ---|
|--- 请输入指令代码 :'''
    while True:
            chosen=False
            while not chosen:#保证输入指令合法,只有在输入不合法时才会重新执行
                choice=input(prompt)
                if choice not in 'NnEeQq':
                    print("您输入的指令代码有误,请重新输入:")
                else:
                    chosen=True
            if choice=='q' or choice=='Q':
                break
            if choice=='N' or choice=='n':
                new()
            if choice == 'e' or choice == 'E':
                old()
showmenu()

54.集合的元素具有唯一性,如果你写了重复的会自动剔除;集合不支持索引;
集合也是利用哈希存储的,所以相同的元素会得到相同的哈希地址,所以集合中元素具有唯一性(最后相同的都被覆盖了),且由于哈希,集合是无序存放的
55.在使用路径名时,windows即可以接受 / 也可以接受 \ 不过使用\作为路径名的分隔符是,注意要使用双反斜线\来转义,否则python会进行反斜线转义(在路径前加r也可)
56.x和w均是以可写入的模式打开文件,但以x,如果路径下已存在相同文件名,会刨出异常,而w会直接覆盖同名文件(使用时会易使此前内容丢失,所以使用前先检查是否有同名)
57.f.read()是从当前文件指针开始读取
58.比较两个文件不同处,且输出个数,及所在行数:

def compare(file1,file2):
    f1=open(file1)
    f2=open(file2)
    count=0#统计行数
    differ=[]#统计不一样的是那些行
    for line1 in f1:#f1的长度为基准,
        line2=f2.readline()
        count+=1
        if line1!=line2:
            differ.append(count)
    f1.close()
    f2.close()
    return differ
file1=input("请输入需要比较的头一个文件名:")
file2=input("请输入需要比较的另一个文件名:")
differ=compare(file1,file2)
if len(differ)==0:
    print("两个文件完全一样!")
else:
    print("两个文件共有%d处不同"%len(differ))
    for i in differ:
        print("第%d行不一样"% i)

59.实现单词或字符替换的功能:

'''实际效果:
请输入文件名:E:/sth2.txt
请输入索要替换的单词或字符:红色高跟鞋
请输入新的单词或字符:绿色高跟鞋

文件 E:/sth2.txt 中共有3个【红色高跟鞋】
您确定要把所有的【红色高跟鞋】替换为【绿色高跟鞋】吗?
【YES/NO】:yes'''
def replacewords(file,rep,new):
    f=open(file)
    content=[]
    count=0
    for eachline in f:
        if rep in eachline:
            count+=eachline.count(rep)
            eachline=eachline.replace(rep,new)
        content.append(eachline)#不管这一行是否有所要替代的都放入其中
    decide=input('\n文件 %s 中共有%d个【%s】\n您确定要把所有的【%s】替换为【%s】吗?\n【YES/NO】:'%(file,count,rep,rep,new))
    if decide in ['YES','Yes','yes']:
        fwrite=open(file,'w')
        fwrite.writelines(content)
        fwrite.close()
        #因为第一次是读取文件修改,但因为是以只读形式不能直接修改,先存入列表,然后重新打开以w形式覆盖源文件,再利用writelines存入
    f.close()
file=input("请输入文件名:")
rep=input("请输入索要替换的单词或字符:")
new=input("请输入新的单词或字符:")
replacewords(file,rep,new)

60.用户可选择行数输出:

'''实际效果
请输入要打开的文件(C:\\test.txt):E:\\sth2.txt
请输入需要显示的行数【格式如13:21 or :21 or :】:2:12

文件E:\\sth2.txt从2行到12行的内容如下:

拿什么跟你作比较才算特别2
 对你的感觉 强烈
 却又不太了解 只凭直觉
 你像窝在被子里的舒服3
 却又像风 捉摸不住4
 像手腕上散发的香水味
 像爱不释手的 绿色高跟鞋
 该怎么去形容你最贴切
 拿什么跟你作比较才算特别
 对你的感觉 强烈
 却又不太了解 只凭直觉
 '''
def fileview(file,line):
    if line.strip()==':':
        #strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
        begin='1'
        end='-1'
    (begin,end)=line.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,prompt))
    begin=int(begin)-1
    end=int(end)
    hangshu=end-begin
    f=open(file)
    for i in range(begin):#用于消耗掉range之前的内容
        f.readline()
    if hangshu<0:
        print(f.read())#end是负数,直接读到文件尾
    else:
        for j in range(hangshu):
            print(f.readline(),end=" ")
    f.close()
file=input(r'请输入要打开的文件(C:\\test.txt):')
line=input("请输入需要显示的行数【格式如13:21 or :21 or :】:")
fileview(file,line)

61.计算当前文件下所有文件大小:

import os
allfiles=os.listdir(os.curdir)#使用os.curdir表示当前目录更为标准
filedict=dict()
for eachfile in allfiles:
    if os.path.isfile(eachfile):
        filesize=os.path.getsize(eachfile)
        filedict[eachfile]=filesize
#print(filedict)
for each in filedict.items():
    print('%s【%dBytes】'%(each[0],each[1]))

62.计算当前目录下每个文件类型的文件数:

'''效果:
该文件共有类型为【.cfg】的文件1个
该文件共有类型为【.py】的文件1个
该文件共有类型为【.json】的文件1个
'''
import os
allfiles=os.listdir(os.curdir)#使用os.curdir表示当前目录更为标准
list1=[]
for i in allfiles:
   if os.path.isfile(i):#先判断是不是文件
     (fname,fext)=os.path.splitext(i)
     list1.append(fext)
#print(list1)
set1=set(list1)
for i in set1:
    count=0
    for j in allfiles:
        if i in j:
            count+=1
    print("该文件共有类型为【%s】的文件%d个"%(i,count))
#考虑有文件夹,输出文件夹个数的
'''该文件下共有类型【.cfg】的文件1个
该文件下共有类型【.json】的文件1个
该文件下共有类型【文件夹】的文件3个
该文件下共有类型【.py】的文件1个
'''
import os
allfile=os.listdir(os.curdir)
typedict=dict()
for each in allfile:
    if os.path.isdir(each):
        typedict.setdefault('文件夹',0)
        typedict['文件夹']+=1
    else:
        ext=os.path.splitext(each)[1]
        typedict.setdefault(ext,0)#如果没有这个后缀名,就增加一项,如果有就返回该键的对应值,不影响
        typedict[ext]+=1
for each in typedict.keys():
    print("该文件下共有类型【%s】的文件%d个"%(each,typedict[each]))

63.用户输入文件名,以及开始搜索的路径,搜索文件是否存在,如遇到文件夹则进入继续搜索:

'''效果:
请输入待查找的初始目录:E:\\
请输入需要查找的目标文件:eg1.py
E:\python\untitled2\venv\eg1.py
'''
def searchfile(start,target):
    os.chdir(start)
    for each in os.listdir(os.curdir):
        if each==target:
            print(os.getcwd()+os.sep+each)#使用os.sep(分隔符)程序更标准
        if os.path.isdir(each):
            searchfile(each,target)#递归
            os.chdir(os.pardir)#递归调用后切记返回上一层目录
start=input("请输入待查找的初始目录:")
target=input('请输入需要查找的目标文件:')
searchfile(start,target)

64.用户输入搜索路径,查找该路径下(包括子文件)所有的视屏格式,并创建一个文件存放所有找到的文件路径

import os
def searchfile(start,target):
    os.chdir(start)
    for each in os.listdir(os.curdir):
        if os.path.isfile(each):
            ext=os.path.splitext(each)[1]
            if ext in target:
                vedeolist.append(os.getcwd()+os.sep+each+os.linesep)#使用os.sep(分隔符)程序更标准,os.linesep结束符
        if os.path.isdir(each):
            searchfile(each,target)#递归
            os.chdir(os.pardir)#递归调用后切记返回上一层目录
programdir=os.getcwd()
start=input("请输入待查找的初始目录:")
target=['.mp4','.avi','rmvb']
videolist=[]
searchfile(start,target)
f=open(programdir+os.sep+'vediolist.txt','w')
f.writelines(videolist)
f.close()

64.输入关键字,查找当前文件夹内(包括子文件夹)所有含该关键字的文本文件txt,要求显示该文件所在位置,及关键字在文件中的具体位置:
注:os.walk(top)
遍历top路径以下所有的子目录,返回一个三元组:(路径, [包含目录], [包含文件])

'''效果:
请将该脚本放于待查找的文件夹内,请输入关键字:sy
请问是否需要打印关键字【sy】在文件中的具体位置(yes/no):yes
======================================
在文件【.\sth.txt】中,找到关键字【sy】
关键字出现在第1行,第[1]个位置。
======================================
在文件【.\新建文本文档 (2).txt】中,找到关键字【sy】
关键字出现在第1行,第[1]个位置。
======================================
在文件【.\新建文本文档.txt】中,找到关键字【sy】
关键字出现在第1行,第[1]个位置。
关键字出现在第2行,第[1]个位置。
关键字出现在第3行,第[1]个位置。
======================================
在文件【.\Lib\site-packages\pip-10.0.1-py3.5.egg\EGG-INFO\SOURCES.txt】中,找到关键字【sy】
关键字出现在第105行,第[29]个位置。
关键字出现在第214行,第[35]个位置。
关键字出现在第215行,第[35]个位置。
关键字出现在第264行,第[26]个位置。
'''
import os
def printpos(keydict):#输出结果
    keys=keydict.keys()
    keys=sorted(keys)#因为字典是无序的,我们这里对行数进行排序
    for each in keys:
        print('关键字出现在第%s行,第%s个位置。'%(each,str(keydict[each])))
def posinline(line,key):#确定key在每一行的位置
    pos=[]
    begin=line.find(key)
    while begin!=-1:
        pos.append(begin+1)#用户的角度是从1开始数
        begin=line.find(key,begin+1)
    return pos
def searchinfile(filename,key):#打的部件用来控制文件的打开,和构成字典
    f=open(filename)
    count=0#记录行数
    keydict=dict()#字典,用户存放key所在具体函数对应具体位置
    for each in f:
        count+=1
        if key in each:
            pos=posinline(each,key)#每一行key出现的位置
            keydict[count]=pos#字典的值是一个列表,因为可能出现在很多位置
    f.close()
    return keydict
def searchfile(key,detail):
    allfiles=os.walk(os.getcwd())#os.curdir可
    txtfiles=[]
    for i in allfiles:
        for eachfile in i[2]:
            if os.path.splitext(eachfile)[1]=='.txt':#根据后缀判断是否文本文件
                eachfile=os.path.join(i[0],eachfile)#将两部分组合成一个文件名
                txtfiles.append(eachfile)
    for eachtext in txtfiles:
        keydict=searchinfile(eachtext,key)#通过上述得到的路径,对每一个txt文件进行关键字的检查
        if keydict:
            print("======================================")
            print("在文件【%s】中,找到关键字【%s】"%(eachtext,key))
            if detail in ['Yes','yes','YES']:
                printpos(keydict)
key=input("请将该脚本放于待查找的文件夹内,请输入关键字:")
detail=input("请问是否需要打印关键字【%s】在文件中的具体位置(yes/no):"% key)
searchfile(key,detail)

65.处理异常,一个try可以和多个except搭配
66.try语句中一旦检测到异常,剩下的语句将不会执行直接跳到处理异常的位置:

#类型出错啦!,错误的原因是:unsupported operand type(s) for +: 'int' and 'str'
try:
    sum=1+'1'
    f=open("我为什么是一个文件.txt")
    print(f.read())
    f.close()
except OSError as reason:
    print("文件出错啦!,错误的原因是:"+str(reason))
except TypeError as reason:
    print("类型出错啦!,错误的原因是:" + str(reason))
#也可以放在一起综合判断:
try:
    sum=1+'1'
    f=open("我为什么是一个文件.txt")
    print(f.read())
    f.close()
except (OSError,TypeError):
    print("出错啦")

67.finally:是用来保证无论怎么样都会执行的语句
如果try语句没有任何错误,会跳过except执行finally
如果有错,会跳入到except来执行代码,最后仍会执行finally

try:
    f=open("我为什么是一个文件.txt",'w')
    print(f.write("i have already existed! "))
    sum=1+'1'
except (OSError,TypeError):
    print("出错啦")
finally:
    f.close()
    #报错后,关闭文件语句没有执行,所以虽然完成了写入操作但是打开文件没有数据(没有被保存)

68.可用raise+具体的异常,来引发异常:raise KeyboardInterrupt
69.带有处理异常的猜数字(包括输入不为整形数据,ctrl +d产生的EOFerror,ctrl+c产生的Keyboardinterrupt)

import  random
secret=random.randint(1,10)
try:
    temp=input("请输入要猜的数字:")
    guess=int(temp)#就算写入浮点性也会算错
except(ValueError,EOFError,KeyboardInterrupt):
    print("输入错误")
    guess=secret#退出下面的循环
while guess!=secret:
    temp=input("猜错了,请重新输入:")
    guess=int(temp)
    if guess==secret:
        print("答对了!")
    else:
        if guess>secret:
            print("bigger")
        else:
            print("smaller")
print("game over")

70.当我们想利用try except写一个打开文件,文件不存在的异常时,如果在finally语句中写f.close()会报错,因为如果这个文件没打开,而试图去关闭一个没打开的文件是不可能的,指代文件变量也是不存在的,但我们必须要写f.close(),因为如果文件存在必须要执行这一步:

try:
    f=open("file.txt")#当前文件夹中不存在file,txt
    print(f.read())
except OSError as reason:
    print("出错啦:"+str(reason))
finally:
    if 'f' in locals():#如果稳健对象变量存在当前局部变量符号表的话,说明打开成功
          f.close()

71.else除了和if搭配,还能和while,for循环搭配,如果循环里的语句完整执行完了,就执行else语句,如果中间有用break退出循环,else不会被执行:
还可以与异常处理进行搭配:只要try语句没有出现任何异常就会执行else里的内容
72.用with可以不用考虑文件的关闭,他会自动进行:
如果中途出现异常,会执行清理代码,确保文件自动关闭

with open('data.txt') as f:

-----------
with A() as a:
  with B() as b:
    suite
等价于=>
with A() as a,B() as b:
    suite

73.面向对象的特征:封装,继承,多态
74.python类的私有是伪私有,即定义类的时候,属性前加上双下划线,在对象时就不能直接访问,可通过构造方法来访问,但是还可以用,对象._类名__变量名访问到
75.在这里插入图片描述

import random as r
legalx=[0,10]
legaly=[0,10]
class Turtle:
    def __init__(self):
        self.power=100#初始体力
        #初始位置随机
        self.x=r.randint(legalx[0],legalx[1])
        self.y = r.randint(legaly[0], legaly[1])
    def move(self):
        #随机计算方向并移动到新的位置(x,y)
        newx=self.x+r.choice([1,2,-1,-2])
        newy=self.y+r.choice([1,2,-1,-2])
        #检查移动后是否超出场景x轴边界,如果超过往反方向走
        if newx<legalx[0]:
            self.x=legalx[0]-(newx-legalx[0])
        elif newx>legalx[1]:
            self.x=legalx[1]-(newx-legalx[1])
        else:
            self.x=newx
        # 检查移动后是否超出场景y轴边界,如果超过往反方向走
        if newy < legaly[0]:
            self.y = legaly[0] - (newy - legaly[0])
        elif newy > legaly[1]:
            self. y = legaly[1] - (newy - legaly[1])
        else:
            self.y = newx
        self.power-=1
        return (self.x, self.y)
    def eat(self):
        self.power+=20
        if self.power>100:
            self.power=100

class Fish:
    def __init__(self):
        # 初始位置随机
        self.x = r.randint(legalx[0], legalx[1])
        self.y = r.randint(legaly[0], legaly[1])

    def move(self):
        # 随机计算方向并移动到新的位置(x,y)
        newx = self.x + r.choice([1,-1])
        newy = self.y + r.choice([1,-1])
        # 检查移动后是否超出场景x轴边界,如果超过往反方向走
        if newx < legalx[0]:
            self.x = legalx[0] - (newx - legalx[0])
        elif newx > legalx[1]:
            self.x = legalx[1] - (newx - legalx[1])
        else:
            self.x = newx
        # 检查移动后是否超出场景y轴边界,如果超过往反方向走
        if newy < legaly[0]:
            self.y = legaly[0] - (newy - legaly[0])
        elif newy > legaly[1]:
            self.y = legaly[1] - (newy - legaly[1])
        else:
            self.y = newx
        return(self.x,self.y)
turtle=Turtle()
fish=[]
for i in range(10):
    newfish=Fish()
    fish.append(newfish)
while True:
    if not len(fish):
        print("鱼儿吃完了,游戏结束!")
        break
    if not turtle.power:
        print("乌龟体力耗尽了")
        break
    pos=turtle.move()
    #在迭代器中删除列表元素是非常危险的,经常会出现意想不到的问题
    #因为迭代器是直接引用列表的数据进行引用
    #这里我们把列表拷贝给迭代器,然后对原列表进行删除操作就不会有问题了
    for each in fish[:]:
        if each.move()==pos:
            #鱼儿被吃
            turtle.eat()
            fish.remove(each)
            print("有一条鱼儿被吃掉啦")

__init__方法不应当返回除了None的任何对象

#TypeError: __init__() should return None, not 'str'
class Myclass:
    def __init__(self):
        return 'this is wrong'
my=Myclass()

77.想屏蔽父类的方法,可以在子类再次定义同名函数,函数体内写pass即可
78.简单的点类,和直线类
直线有两点构成,初始化时需要两个点对象作为参数

import random as r
import math
class Point:
    def __init__(self,x=0,y=0):
        self.x=x
        self.y=y
    def getx(self):
        return self.x
    def gety(self):
        return self.y
    def setxy(self,x,y):
        self.x = x
        self.y = y
class Line:
    def __init__(self,a,b):
        self.x=abs(a.getx()-b.getx())#不让他直接去访问而是利用接口,这样才有类的封装
        self.y = abs(a.gety() - b.gety())
        self.len=math.sqrt(self.x*self.x+self.y*self.y)
    def getlen(self):
        return self.len
p1=Point(4,5)
p2=Point(1,1)
line=Line(p1,p2)
print(line.getlen())

79.类的组合就是把类的实例化放到一个新类里去,把横向关系(没有继承关系)的类组合起来:

class Turtle:
    def __init__(self,x):
        self.num=x
class Fish:
    def  __init__(self,x):
        self.num=x
class Pool:
    def __init__(self,x,y):
        self.turtle=Turtle(x)
        self.fish=Fish(y)
    def print_num(self):
        print("水池里共有乌龟%d只,小鱼%d条"%(self.turtle.num,self.fish.num))
pool=Pool(1,10)
pool.print_num()

80.属性的名字和方法相同,属性会覆盖方法
81.组合和继承的使用:
根据实际场景来确定,组合适用于“有一个”的场景,继承适用于“是一个”的场景,比如:水里有鱼虾,天上有星月。(组合)西瓜是瓜,鹦鹉是鸟(继承)
82.类对象在类定义完后就产生,类定义就变成了类对象,可直接通过类名.属性,类名.方法来引用或使用相关方法
83.python要求方法有实例才能被调用
84.写一个类,类中有一个变量来跟踪有多少实例被创建和销毁,每有一个就加一,少一个减一

class Classical:
    count=0
    def __init__(self):
        Classical.count+=1
        print("这是第%d个实例"%Classical.count)
    def __del__(self):
       Classical.count -= 1
c=Classical()
b=Classical()
del c
print(Classical.count)

85.在Python中,False,0,’’,[],{},()都可以视为假
86.定义了一个栈类,具备判断是否为空,pop,top,bottom,push能力:

class Stack:
    def __init__(self,start=[]):
        self.lists=[]
        for x in start:
            self.push(x)
    def isempty(self):
        if len(self.lists)==0:
            return False
        else:
            return True
    def push(self,x):
        self.lists.append(x)
    def pop(self):#出栈需要先判断栈是否为空
        if not self.lists:
            print("warning:the stack is empty!")
        else:
            self.lists.pop(len(self.lists)-1)
    def top(self):
        if not self.lists:
            print("warning:the stack is empty!")
        else:
            print(self.lists[len(self.lists)-1])
    def bottom(self):
        if not self.lists:
            print("warning:the stack is empty!")
        else:
            print(self.lists[0])
'''stack=Stack()
for i in range(5):
    stack.push(i)
stack.top()
stack.bottom()'''

87.在利用isinstance(object,classinfo)判断是否为该实例是否为某一类时,如果写入的类是在对象所在类的父类也会返回true且如果第二个参数不是类or类组成的元组,会返回一个typeError的异常;classinfo不仅可以是类也可以是一个类对象构成的元组,只要于其中一个满足,就返回true;如果第一个参数不是对象则永远返回false
88.hasattr(object,name)是一个bif可以直接使用(判断该对象是否有此属性),不需要前缀,第二个参数需要以字符串形式表示(加双单引号)
89.一个类可视作自身的子类
90.__init__方法返回none,所以我们在写的时候也要注意不要给init方法任何返回值
91.当你继承一个不可变类型时,又要对其进行修改,要重写__new__方法
92.当所有指向实例的引用都被删除后,系统才会启动垃圾回收机制,自动调用__del__方法(对象将要被销毁时调用) del x!=x.__del() __
93,定义一个类,继承于int,要简练的实现功能(直接利用print输出),并实现一个特殊功能:当传入字符串时,返回所有字符ascii码和
利用new返回一个实例对象,来直接得出结果

#print(Nint('FishC'))  461
#print(Nint(123))  123
#print(Nint(1.5))   1
class Nint(int):
    def __new__(cls,arg=0):
        if type(arg)==str:
            sum=0
            for i in arg:
                sum+=ord(i)
            return int.__new__(cls,sum)
        else:
            return int.__new__(cls,arg)

94.工厂函数其实就是类对象,当你调用它的时候就是创造一个实例对象
95.类的属性名和方法名绝对不能相同
96.定义一个类支持字符串相减a-b从a中除去所有b的子字符串

class Nstr(str):
    def __sub__(self, other):
        return self.replace(other, '')
        '''self=list(self)
        print(self)
        other=list(other)
        for i in self:
            if i in other:
                self.remove(i)#少替换的原因理解为,每找到一个去掉,list长度减少,所以也无法达成全部解锁
        ans=''
        for i in self:
            ans+=i
        return ans '''
a=Nstr('I love Fshc.com!iiii')
b=Nstr('i')
print(a-b)

#定义一个类Nstr,当该类的实例对象间发生加减乘除运算时,将该对象的所有字符串之间的ascii吗和进行计算
class Nstr:
    def __init__(self,arg=''):
        if isinstance(arg,str):
            self.total=0
            for i in arg:
                self.total+=ord(i)
        else:
            print("参数错误")
    def __add__(self, other):
        return self.total+other.total
    def __sub__(self, other):
        return self.total-other.total
    def __mul__(self, other):
        return self.total*other.total
    def __truediv__(self, other):
        return self.total/other.total
    def __floordiv__(self, other):
        return self.total//other.total
a=Nstr('sas')
b=Nstr('love')
print(a+b,a-b,a*b,a/b,a//b)

也可以

#定义一个类Nstr,当该类的实例对象间发生加减乘除运算时,将该对象的所有字符串之间的ascii吗和进行计算
class Nstr(int):
    def __new__(cls, arg=0):
        if isinstance(arg,str):
            total=0
            for each in arg:
                total+=ord(each)
            arg=total
        return int.__new__(cls,arg)
#利用new返回实例对象,在生成时计算出字符串ascii吗的和,返回int类型实例对象,自然加减乘除都可以正常使用不必重写
a=Nstr('sas')
b=Nstr('love')
print(a+b,a-b,a*b,a/b,a//b)

98.魔法方法的反运算(在前者不支持或没有实现运算时 )他的参数self,other,self指的是后项,而other指的是前项用的时候注意顺序
99.在继承的类中调用基类方法:用super()(里面好像可以不用写参数如self,他会自动去寻找父类,调用父类方法)

class Derived(Base):
	def meth(self):
	    super(Derived,self).meth()

100.类的静态属性即在类中直接定义的变量(没有self.),引用静态属性使用类名.属性名的形式
101.静态方法

#类的静态方法的使用
#静态方法是类的特殊方法,静态方法只需要在普通方法的前面加上@staticmethod修饰符即可
#静态方法最大的优点就是不会绑定到实例对象上,换而言之即节省开销
class C:
    @staticmethod#该修饰符表示static()是静态方法
    def static(arg1,arg2,arg3):
        print(arg1,arg2,arg3,arg1+arg2+arg3)
    def nostatic(self):
        print("i am just a normal method")
c1=C()
c2=C()
#静态方法只在内存中生成一个,节省开销
print(c1.static is C.static)#True
print(c2.static is C.static)#True
print(c1.static)#<function C.static at 0x000001C2298526A8>
print(c2.static)#<function C.static at 0x00000190598A2378>
print(C.static)#<function C.static at 0x000001E8887F2378>
#普通方法每个实例对象都拥有独立的一个开销较大
print(c1.nostatic)#<bound method C.nostatic of <__main__.C object at 0x000001E5F3AC88D0>>
print(c2.nostatic)#<bound method C.nostatic of <__main__.C object at 0x000001E5F3AC8908>>
print(C.nostatic)#<function C.nostatic at 0x000001E5F3AC26A8>
#使用需注意的地方:静态方法不需要self参数,因为即使是使用对象去访问,self参数也不会传进去
print(c1.static(1,2,3))#1 2 3 6
print(C.static(1,2,3))# 1 2 3 6

102.计算函数在给定次数的运行时间:

import time as t
class Mytimer():
    def __init__(self,func,number=1000000):
        #self.unit=['年','月','天','小时','分钟','秒']
        #self.borrow=[0,12,31,24,60,60]
        self.prompt='未开始计时'
        self.begin=0
        self.end=0
        self.number=number
        self.lasted=0.0
        self.func=func
        self.defaulttimer=t.perf_counter
    def __str__(self):
        return self.prompt
    __repr__=__str__
    def __add__(self, other):
       result=self.lasted+other.lasted
       prompt="总共运行了%0.2f秒"%result#临时使用做局部变量
       return result
    def timing(self):
        self.begin=self.defaulttimer()
        for i in range(self.number):
            self.func()
        self.end=self.defaulttimer()
        self.lasted=self.end=self.begin
        self.prompt="总共运行%0.2f秒"%self.lasted
    def settimer(self,timer):
        if timer=='process_time':
            self.defaulttimer=t.process_time
        elif timer=='perf_counter':
            self.defaulttimer=t.perf_counter
        else:
            print("输入无效")
    '''#开始计时
    def start(self):
        self.begin=t.localtime()
        self.prompt='请先调用stop停止计时'
        print("计时开始...")
    #停止计时
    def stop(self):
        if not self.begin:
            print("请先调用start进行计时")
        else:
            self.end=t.localtime()
            self._calc()
            print("计时结束...")
    #内部方法计算运行时间
        def _calc(self):
        self.lasted=[]
        self.prompt='总共运行了'
        for index in range(6):
            temp=self.end[index]-self.begin[index]
            #低位不够,需向高位借位
            if temp<0:
                i=1
                while self.lasted[index-i]<1:
                    self.lasted[index-i]+=self.borrow[index-i]-1
                    self.lasted[index-i-1]-=1
                    i+=1
            else:
                self.lasted.append(temp)
        for index in range(6):
            if self.lasted[index]:
                self.prompt+=str(self.lasted[index])+self.unit[index]
        #为下一轮计时变量初始化
        self.begin=0
        self.end=0 '''
def test():
    text='i love you'
    char= 'o'
    if char in text:
        pass
t1=Mytimer(test)
t1.settimer('process_time')
t1.timing()
print(t1)
t2=Mytimer(test,10000000)
t2.settimer('process_time')
t2.timing()
print(t2)
print(t1+t2)

103.此代码有错吗,若有请指出:

def __setattr__(self, nam, value):
        self.name = value + 1
        #这段代码试图在对象的属性发生赋值操作的时候,将实际得值+1赋值给属性,但这么写法是错误的,因为每当属性被赋值的时候,__setattr__会被调用,而里边的self.name = value + 1语句又会再次触发__setattr__调##用,导致无限递归

改正:

def __setattr__(self, nam, value):
	self.__dict__[name]=value+1
#------
def __setattr__(self, nam, value):
	super().__setattr__=value+1

104.访问类中不存在的属性,先访问__getattribute__,发现找不到属性名,在访问__getattr__,注意object基类无__getattr__方法
super访问报错AttributeError
105.检查代码并改错使之能正确运行:

class Counter:
    def __init__(self):
        self.counter=0#这里会触发—__setattr__调用
    def __setattr__(self, key, value):
        self.counter+=1
        super().__setattr__(key,value)
        #既然__setattr__调用后才能设置self.counter的值,所以这时候self.counter还没有定义,所以没法+=1,错误根源
    def __delattr__(self, item):
        self.counter-=1
        super().__delattr__(item)

正确:

class Counter:
    def __init__(self):
        super().__setattr__('counter',0)#里面也可以写具体的参数,而不只是指代的
    def __setattr__(self, key, value):
        super().__setattr__('counter',self.counter+1)
        super().__setattr__(key,value)
    def __delattr__(self, item):
        super().__setattr__('counter',self.counter-1)
        super().__delattr__(item)
c=Counter()
c.x=1
print(c.counter)
c.y=1
c.z=1
print(c.counter)
del c.x
print(c.counter)

106.描述符必须定义在类的层次上而不是实例的层次上,若定义在实例层次上,则会返回描述符本身类似<function C.static at 0x000001E8887F2378>

class Mydes:
    def __get__(self, instance, owner):
        print("getting...")
class Test:
    a=Mydes()
test=Test()
print(test.a)
class Mydes:
    def __init__(self,value=None):
        self.val=value
    def __get__(self, instance, owner):
        return self.val**2
class Test:
    def __init__(self):
        self.x=Mydes(3)
test=Test()
print(test.x)
#<__main__.Mydes object at 0x000002248EDA8550>

107.编写描述符,记录指定变量的读取和写入,并将记录和触发时间保存到文件record.txt中

import time
class Record:
    def __init__(self,value=None,name=None):
       self.name=name
       self.value=value
       self.filename="Record.txt"
    def __get__(self, instance, owner):
        with open (self.filename,'a',encoding='utf-8')as f:
            f.write('%s 变量于北京时间 %s 被读取,%s=%s\n'% \
                    (self.name,time.ctime(),self.name,str(self.value)))
        return self.value
    def __set__(self, instance, value):
        #filename = '%s_record.txt' % self.name
        with open(self.filename, 'a', encoding='utf-8')as f:
            f.write('%s 变量于北京时间 %s 被修改,%s=%s\n'% \
                    (self.name,time.ctime(),self.name,str(value)))
        self.value=value

class Test:
      x=Record(10,'x')
      y=Record(8.8,"y")
test=Test()
print(test.x)
print(test.y)
test.x=123
test.x=1.23
test.y='i love you'

在这里插入图片描述
108.
在这里插入图片描述

import os
import pickle
class Mydes:
    saved=[]#记录已有属性值,来为get做判断,防止访问没有的属性
    def __init__(self,name=None):
      self.name=name
      self.filename=self.name+'.pkl'
    def __get__(self, instance, owner):
        if self.name not in Mydes.saved:
           raise AttributeError('%s属性还没有被赋值!' %self.name)
        with open(self.filename,'rb') as f:
            value=pickle.load(f)
        return value
    def __set__(self, instance, value):
       with open(self.filename,'wb') as f:
            pickle.dump(value,f)#存入pickle中
            Mydes.saved.append(self.name)
    def __delete__(self, instance):
        os.remove(self.filename)
        Mydes.saved.remove(self.name)


class Test:
      x=Mydes('x')
      y=Mydes("y")
test=Test()
#print(test.x)
#print(test.y)
test.x=1.23
test.y='i love you'
del test.x

109.简单定义一个不可变容器:(只完成getitem方法和len)
(可变的是加上setitem和delitem)

class C:
    def __init__(self,*args):
        self.values=[x for x in args]
        self.count={}.fromkeys(range(len(self.values)),0)#创建一个字典,key是每个参数的下标,value是存的访问的次数
    def __len__(self):
        return len(self.values)
    def __getitem__(self, item):
       self.count[item]+=1
       return (self.values[item])
c=C(1,3,5,7,9)
c2=C(2,4,6,8,10)
print(len(c))
print(c[1])
print(c.count)

在这里插入图片描述

#基于上题,将其改为可变类型的容器,仍然统计每个元素访问次数,但要求功能更加全面
#解析:为了实现这么多功能,我们不能再用字典存放元素的计数,因为对于列表来说,你删除了其中一个元素,那么其他元素得下标都会变化
#而利用下标作为键的字典肯定就不能应对自如,因此,我们改用一个列表来存放对应的元素计数
class C(list):
    def __init__(self,*args):
        super().__init__(args)#即创建一个list列表,存着参数
        self.count=[]
        for i in args:
            self.count.append(0)
    def __len__(self):
        return len(self.count)
    def __getitem__(self, item):
       self.count[item]+=1#访问次数加1
       return super().__getitem__(item)#调用list的getitem返回值
    def __setitem__(self, key,value):#key是指在列表中的位置
        self.count[key]+=1#set是对已有的列表元素进行修改,而不是生成新的所以不是append
        super().__setitem__(key,value)
    def __delitem__(self, key):
        del self.count[key]
        super().__delitem__(key)
    def counter(selfself,key):
        return self.count[key]
    def append(self, value):
        self.count.append(0)
        super().append(value)#调用基类list,增加值
    def pop(self,key=-1):
        del self.count[key]
        return super().pop(key)#删除几号元素
    def remove(self, value):
        key=super().index(value)#确定所删元素位置
        del self.count[key]
        super().remove(value)
    def insert(self,key,value):
        self.count.insert(key,0)
        super().insert(key,value)
    def clear(self):
        self.count.clear()
        super().clear()
    def reverse(self):
        self.count.reverse()
        super().reverse()
    
c=C(1,3,5,7,9)
c2=C(2,4,6,8,10)
print(len(c))
print(c[1])
print(c.count)

111.迭代器不是容器(能存放数据的像列表字典元组),是实现了__next()__方法的对象,用于遍历容器中的数据
112.判断一个容器有没有迭代功能就是看他有没有iter和next方法
113.Python原生支持的数据结构中,只有set是只能用迭代器访问的,对于原生支持随机访问的数据结构如tuple,list可以使用迭代器或者下标索引的形式访问,但对于无法随机访问的数据结构set而言,迭代器是唯一的访问方式
112。写一个迭代器,输出至今为止所有的闰年

class Leapyear:
    def __init__(self):
        self.year=2020
    def __iter__(self):
        return self
    def isleapyear(self,year):
        if(year%4==0 and year%100!=0) or(year%400==0):
            return True
        else:
            return False
    def __next__(self):
        while not self.isleapyear(self.year):
            self.year-=1
        temp=self.year
        self.year-=1
        return temp

leapyear=Leapyear()
for i in leapyear:
    if i>=2000:
        print(i)
    else:
        break

113.写一个类,功能与reversed()相同(内置函数reversed(seq),返回一个迭代器是序列seq的逆序显示):

class Mydev:
    def __init__(self,string):
        self.string=string
        self.length=len(self.string)
    def __iter__(self):
        return self
    def __next__(self):
        if self.length>0:
            self.length-=1
            temp=self.string[self.length]
            return temp
        else:
            raise StopIteration

mydev=Mydev('赵兄托我帮你办点事')#n(*≧▽≦*)n
for i in mydev:
    print(i,end="")

#列表推导式
a=[i for  i in range(100) if not(i%2) and i%3 ]
print(a)
#字典推导式
b={i:i%2==0 for i in range(10)}
print(b)
#集合推导式
c={i for i in [1,1,2,3,4,5,5,6,7,3,2,1]}
print(c)
#没有字符串推导式,出现了双引号就把里面如实打印
d="i for in 'i love you'"
print(d)#i for in 'i love you'
e= (i for i in range(10))
print(e)#<generator object <genexpr> at 0x0000025A80915150>是生成器推导式不是元组推导式
print(next(e))

115.生成器补充:
在这里插入图片描述
116.python的模块就是程序,每一个.py结尾的文件都是一个独立的模块
117.若两个模块有相同的函数名,且是利用from,import来引入的,则调用该函数时,哪个模块在后引入,则这个模块的函数起效,这就是命名空间的冲突,写时尽量避免使用from import方式来引入。
118.在这里插入图片描述
在这里插入图片描述

119.在这里插入图片描述
在这里插入图片描述

class Const:
    def __setattr__(self, key, value):
        if key in self.__dict__:
            raise TypeError('常量无法改变!')
        if not key.isupper():
            raise TypeError("常量名必须有大写字母组成!")
        self.__dict__[key]=value
    import sys
    sys.modules[__name__]=Const()

120.__name__含义:
所有模块都有一个此属性,name__得值取决于如何应用模块,在作为独立程序运行的时候哦,name__属性的值是__main,而作为模块导入时,这个值就是该模块的名字。
121.python根据文件夹里是否有__init
.py(内容可为空,也可以写一些初始化代码)文件区分是普通文件夹还是包(同类的模块放到一个文件夹中统一管理)
122.解题:

#如何解决:执行a.py,b.py都会报错
#a.py
import b
def x():
    print('x')
b.y()

#b.py
import a
def y():
    priny('y')
a.x()
#解析:因为在执行b.py的加载过程中,需要创建新的模块对象b,然后执行b.py对应的字节码。当遇到第一条语句(import a)时,
#python转而去导入 a.py并生成模块对象a,同样遇到import b时,Python就去导入模块b。此时发现b模块已经导入(在sys.modules中存在)
#继而执行b模块字节码,当执行到a.x()时由于模块a未完全导入,导致抛出attributeError
#b.py()->import a->查找a->未发现a模块对象->导入a.py->import b->查找b模块->发现b模块对象->接着往下执行字节码
#import a已经执行过,python有机制确保不重复导入,因而不会再执行->a.x()->在a模块中找不到x(),因为a没有被完全导入

#正确:
#a.py
import b
def x():
    print('x')
if __name__=="__main__":#只有当为独立程序运行时,才会被执行,破解了上述的错误(是因为作为import执行)
    b.y()

#b.py
import a
def y():
    priny('y')
if __name__ == "__main__":
    a.x()
#判断类型
def func():
    pass
print(type(func()))#<class 'NoneType'>
#判断类型
print(type(1j))#<class 'complex'>
#判断打印内容
dict1={}
dict1[1]=1
dict1[1.0]=3#1=1.0,所以实际修改的key为1的value
dict1['1']=2
result=0
for i in dict1:
    result+=dict1[i]
print(result)#5
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python三级上资料主要包括教材、课件和习题集等内容。 首先,教材是Python三级上学习的重要指导资料。教材通常包括理论知识和实例分析等内容,帮助学生系统地了解Python的基本概念、语法规则和常用函数等。教材一般囊括Python编程的各个方面,如数据类型、控制流程、函数、文件操作、模块与包、错误处理等等。好的教材应该具有条理清晰、语言简洁、实例丰富的特点,方便学生学习和练习。 其次,课件也是Python三级上学习的重要辅助资料。课件一般是教师根据教材和教学计划编制的幻灯片形式的资料,更加直观地呈现了Python的知识点和重点,帮助学生理解和记忆。课件一般配有案例分析、代码示例和练习题等,可供学生课堂上跟随教学使用,回顾和巩固学习内容。 此外,习题集也是Python三级上学习的重要补充资料。习题集一般由教师或者教材编写组提供,包含大量的练习题目,帮助学生深入理解和掌握Python的知识点,提高编程能力。习题集的题目应覆盖教材和课件的内容,按照难易程度和知识点进行分类,学生可以根据自己掌握的程度逐步完成。 总之,Python三级上的资料包括教材、课件和习题集等,通过这些资料的综合使用,学生可以系统地学习和掌握Python的基础知识和编程技巧,为进一步深入学习和应用打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值