python的编程细节总结

1|0一、列表

1|11.删除列表中的元素:

  • 用 del 删除元素会导致列表的剩余元素(从删除元素的后面元素开始)的索引发生变化,一般不建议使用。

  • 用 remove 或 pop 方法移除可不会发生溢出列表长度的错误,remove只会移除首先遍历到的元素,pop() 括号内不写入值时,默认删除最后一个元素,加入就按索引删除元素

  • 列表切片,取到最后一个元素

    lis=[3::] #取索引为3到最后的元素,注意冒号之间没有数字 lis=[len(lis)-1::-1] #倒着取所有元素,包含最后元素,只要倒着取,一定要加负数的步长
  • range() 倒着遍历列表到最后一个元素

    for i in range(len(lis)-1,-1,-1) #注意各个数字

1|22.输出列表中元素的索引:

  • 当列表中有重复的元素时,使用for i in lis_1: 循环时,当要输出i的索引时,若此时i为列表中的重复的元素,则重复的元素的索引会一样即相等,因为系统默认lis_1.index(i)这里的i是一个列表中值,只会输出列表中的最先遍历到的i的索引。

2|0二、字符串

2|11.切割字符串:

  • 切割字符串时,会生成新的列表,原字符串不变化。

  • 字符串的内置方法中,凡是对字符串做修改的操作,字符串本身不会发生变化,想要得到变化后的结果,就要新赋值给一个变量。

    也可当做当对不可变的数据类型做修改操作时,这个不可变的数据类型本身不会发生变化,想要得到变化的结果,需要把变化的东西赋值给一个变量

  • 字符串转换成列表,不用再遍历字符串了。 如:

    s='abcd ef ,g' lis=list(s) print(lis) #打印结果: #['a', 'b', 'c', 'd', ' ', 'e', 'f', ' ', ',', 'g']

2|22. 字符串也可以进行比较,先按首字母比较,相同就比较第二位字母。

3|0三、BUG

  • debug:定位bug,不一定是定位的那一行出错了

4|0四、 读取文本文件

txt文档按行读取时(f.readline()),利用字符串的strip方法切割,把换行符切掉,再利用split方法切割,就可以生成新列表,这样就可以处理按行存储的信息

  • 修改文本文件的原理

    with open('test.txt', 'r', encoding='utf8') as fr,open('test_swap.txt', 'w', encoding='utf8') as fw: # 再大的文件都能修改 data = fr.read() fw.write(data) import os os.remove('test.txt') os.rename('test_swap.txt', 'test.txt')#先是要修改的文件名字,后是修改后的文件名字,replace 也是如此。

5|0五、一些小的技巧

5|11. 字符串

  • 把字符串的字母都变大写

    s='ab cd,f' s=s.upper() #注意,一定一定一定要重新赋值一下,或者直接打印print(s.upper()),否则打印print(s),还是小写的
  • 把字符串的字母都变小写

    用 lower() 方法

5|22. 运算

  • print(1.2 - 1.0 == 0.2) # False #010101010 01010101010# # # 010101010 - 01010101010 # 一些差错# # print(round(1.2 - 1.0)) # 浮点数运算时造成的不确定尾数 小数不比整数,小数的二进制非常复杂,所有当两个小数进行算术运算的时候,会出现错误,这个计算的结果无限接近0.2,但是不等于0.2,因此打印返回的是 Fales 而且小数保留两位的时候,不会四舍五入,只有整数有四舍五入。 但是我们可以用下面的方法得到0.2 就是先把两个运算的浮点数变成整数之后在进行运算。最后再除以10的倍数 n = (1.2*10 - 1.0*10)/10 print(n)

5|33.Python自带的一些东西

  • Python中只要定义变量就会创建新的内存空间,以下为两种特例

    Python里的小整数池,在Python启动时就自动为[-5,256]分配内存空间,也就是说,在这个区间内的整数,它们的内存地址被写死,不会改变。

    而Pycharm中,把这个小整数池扩大了,在很短的一段时间内定义一个变量值相同的变量,他们的内存地址相同。

  • Python中每个数据类型的数据都有对应的布尔值,

    0 / None / 空(空字符、空列表、空字典、空元组) /Falese这些对应的布尔值都为False,其他的为True

  • 存不是目的,取才是目的

  • 深浅拷贝:

    列表,字典等数据类型的内置方法中的 .copy方法都是浅拷贝

    lt2 是 lt1的浅/深复制对象 : 就是lt2 复制了lt1 lt2 = copy.copy(lt1) lt2 = copy.deepcopy(lt1)

5|44. 散列表(哈希表)

字典的key 和集合的元素 都是基于散列表来存储的。索引字典和集合无序,不重复。

6|0六、 集合

乱序:当集合中只有正整数的时候,按升序排序。有正负整数时,正整数升序排序,负数乱序排序,且,且负数在正数后面开始排序。当集合中有正浮点数和符浮点数时,都是按乱序排列,正的排在负的前,正浮点数会乱序在正整数中。

7|0七、 re模块

# findall match search 的区别: s = 'abcd abcddd abc' print(re.findall('abcd*', s)) # ## match: 从开头找一个,找得到就不找了 ;找不到报错 --》 # s = 'ab abcddd abc' # res = re.match('abcd*', s) # print(res.group()) ## search: 从字符串找一个,就不找了 s = 'ab abcddd abc' res = re.search('abcd*', s) print(1115555,res) print(res.group())

8|0八 、迭代器与生成器

#除了数字类型,所有数据类型都是可迭代对象 #为什么要有迭代器对象:提供了 不依赖索引取值的 手段

生成器都是可以用迭代进行取值的,如__next__() ,for循环,还可以使用强制类型转换,转换成列表就可以直接打印出来生成器中的元素。

#for循环原理,本质是可控的while循环 dic = {'a':1,'b':2,'c':3} dic_iter = dic.__iter__() while True: try: print(dic_iter.__next__()) except StopIteration: break
# 生成器 自定义range方法 def re_range(start,stop,step): while start < stop: yield start start += step for i in re_range(0,10,2): print(i)

9|0九、 循环导入问题和解决办法

  • 导模块,模块永远只会开辟一次内存空间,所以当发生循环导入的情况时,不会出现内存满了了的错误,只会发生死循环的错误。 循环导入原理:模块永远只会开辟一次 ; from m1 import 必须得执行m1.py中所有代码,当两个模块互相导入时,就有可能会发生死循环。 1. 在m1中运行m2模块 2. 在m2中运行m1模块 1. 在m1中运行m2模块 2. 在m2中运行m1模块 ...
  • 解决方法

    # 第一种解决方法: # m1.py下: x = 10 from m2 import y print('m1:', x, y) # 第一种解决方法: # m2.py下: y = 20 from m1 import x print('m2:',x,y) # 第二种: 定义函数阶段只检测语法,不执行代码 # m1.py下: def f1(): from m2 import y print('m1:', x, y) x = 10 f1() # 第二种解决方法: # m2.py 下: def f2(): from m1 import x print('m2:', x, y) y = 20

10|0十、 函数和类

  • 函数在调用的时候才开辟名称空间,执行函数内部的代码

  • 类是在定义的时候就会开辟名称空间(把类内部的名称全部丢进类的名称空间里),执行类内部的代码。

  • 名称空间的执行(生成)顺序:

    内置——》全局——》局部

  • 名称空间的搜索顺序:

    先当前位置 局部——》全局——》内置——》报错 (不可逆)

  • 模块的搜索顺序:

    内存中的模块——》内置模块——》自定义模块

  • 对象中名称的搜索顺序:

    • 先对象自己的名称空间——》实例化产生对象的类的名称空间——》父类的名称空间(有多个父类时,按照继承父类的顺序查找)

    • 当类中有self.func()时,还会重新开始从对象开始按上面的顺序搜索

  • 在类中的定义的函数,类自己调用它是它就是普通的函数(function)。当对象调用它时,它是绑定方法 (bound method),且类和不同的对象调用同一个函数时,他们(如Student.func stu1.func stu2.func)的内存地址都不同

11|0十一、 装饰器的特性

对于二层装饰器,多次使用这个装饰器时,装饰器中 两个函数之间的代码,只会在第一次调用装饰器时执行一次,仅这一次,只会调用这个装饰器,会直接从第二个函数运行。

12|0十二、 面向对象之 反射

对象.__dict__ 只返回对象自己的属性(即通过self.属性的这些属性),就是不包过继承的类中类自己的属性

类.__dict__只返回类自己的属性

hasattrgetattr,判断对象时,会查找对象自己的,对象自己没有就去找类的。

13|0十三、 面向对象之 魔法方法(类的内置方法)

__getattr__: 会在执行程序时遇到 对象.属性 或者 getattr 方法时,并且 “属性没有” 的情况下才会触发,对象.属性 或者 getattr 的返回值永远是None __getattribute__ : 会在执行程序时遇到 对象.属性 或者 getattr 方法 时,无论 “属性有或者没有” 的情况下都会触发。无论属性有没有,对象.属性 或者 getattr 的返回值永远是None,使用这两个方法,对象.属性永远不会报错。 当 __getattr__ 和 __getattribute__ 同时存在,只会触发 __getattribute__ 。 __delattr__ : 会在执行程序时遇到删除对象属性(即 del 对象.属性 【属性是对象自己的或者类的】 )时触发 而且 del 对象.属性 并没有删除该属性 del 类名.属性 会删除该属性 ,删除类的属性不会触发 __delattr__ __del__ : 会在要销毁对象时触发 。如:(1del 对象名 。 2)程序执行结束,因此这种情况会在最后执行该方法的代码

14|0十四、 python的一些特点

详情点击本链接

15|0十五、小知识点

  • 在SQL中,字段为枚举类型时,枚举的内容只能用字符串,不能为数字型。
  • 在自定义元类时,如果只对要限制的类的名称空间做一个判断,只需要def __init__(self,class_name,class_bases,class_dic),之后直接在下面进行判断,最后再继承父类即type类的__init__。若要对要限制的类的名称空间进行修改,则需要定义def __new__(cls,class_name ,class_bases,class_dic),在其下面写修改内容,最后返回return type.__new__(cls , class_name , class_bases,class_dic)

16|0十六、文件单位

PB = 1024 TB = 1024^2 GB = 1024^3 MB = 1024^4 KB = 1024^5 bytes = 8*1024^5


__EOF__

本文作者BigSun丶
本文链接https://www.cnblogs.com/Mcoming/p/11461141.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   BigSun丶  阅读(123)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示