• 编程细节总结


    一、列表

    1.删除列表中的元素:

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

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

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

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

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

    2.输出列表中元素的索引:

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

    二、字符串

    1.切割字符串:

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

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

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

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

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

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

    三、BUG

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

    四、 读取文本文件

    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 也是如此。
      

    五、一些小的技巧

    1. 字符串

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

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

      用 lower() 方法

    2. 运算

    • 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)
      

    3.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) 
      

    4. 散列表(哈希表)

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

    六、 集合

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

    七、 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())
    

    八 、迭代器与生成器

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

    生成器都是可以用迭代进行取值的,如__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)
    

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

    • 导模块,模块永远只会开辟一次内存空间,所以当发生循环导入的情况时,不会出现内存满了了的错误,只会发生死循环的错误。
      
      循环导入原理:模块永远只会开辟一次 ; 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
      

    十、 函数和类

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

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

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

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

    • 名称空间的搜索顺序:

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

    • 模块的搜索顺序:

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

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

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

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

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

    十一、 装饰器的特性

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

    十二、 面向对象之 反射

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

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

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

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

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

    十四、 python的一些特点

    详情点击本链接

    十五、小知识点

    • 在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)

    十六、文件单位

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

  • 相关阅读:
    网络时间校对
    OleVariant的本质
    GIT生成SSHKEY公钥放到服务器免密登录
    git 清除所有untracked file
    Linux命令 cat命令
    Linux如何通过命令查看日志文件的某几行(中间几行或最后几行)
    Git提交(PUSH)时记住密码 不用每次都输入密码
    arcgis10 arcmap10插件监控打开和保存文档
    arcmap10插件必看网页
    arcgis分解每一个部分为一个对象
  • 原文地址:https://www.cnblogs.com/Mcoming/p/11461141.html
Copyright © 2020-2023  润新知