zoukankan      html  css  js  c++  java
  • python易错点1

    1.函数的默认参数只初始化一次

    函数的默认值只会创建一次,之后不会再变了,使用对象(列表、字典、实例)作为默认值,会导致函数混乱,如下面的函数在后续调用中积累传递给它的参数

    def f(a, L=[]):
        L.append(a)
        return L
    
    if __name__ == '__main__':
        print(f(1))
        print(f(1))
        print(f(1))
    

      

     可以使用下面的办法进行规避:

    def f1(a, t=None):
        t = t or []
        t.append(a)
        return t
    

      

    2. is与==

    • == 是比较两个对象的内容是否相等,即两个对象的“值“”是否相等,不管两者在内存中的引用地址是否一样。
    • is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。即is比较两个条件:1.内容相同。2.内存中地址相同。
    • 使用is注意python对于小整数使用对象池存储问题,和字符串的intern机制存储问题,并且命令行运行和Pycharm运行有点不一样,因为Pycharm对解释器进行了优化。
    • python中对于None值的比较:使用is,即,要用is或is not none:  she is none; she is not None;
    •  布尔值:不要用==比较布尔值,

    • Python中,万物皆对象!万物皆对象!万物皆对象!(很重要,重复3遍)

      每个对象包含3个属性,id,type,value

      id就是对象地址,可以通过内置函数id()查看对象引用的地址

      type就是对象类型,可以通过内置函数type()查看对象的类型。

      value就是对象的值。

        # is和==的区别
        str1 = 'aaaa'
        str2 = 'bbbbb'
        str3 = 'bbbbb'
        str4 = str3
        print(str1 == str2, str2 == str3, str3 == str4)
        print("str2的地址:", id(str2), "
    str3的地址:", id(str3), "
    id(str2) == id(str3):", id(str2) == id(str3))
    

      

    # 引用地址不一样,但是只要值一样即可==成立。
        val1 = 2000
        val2 = 2001
        val3 = val1 + 1
        print("val1的地址:", id(val1), "
    val2的地址:", id(val2), "
    val3的地址:", id(val3),
              "
    id(val2) == id(val3):", id(val2) == id(val3), "
    val2 == val3:", val2 == val3)
    

      

    # 3.对于类的实例比较
    class Student(object):
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def run(self):
            print("can run")
     
    stu1 = Student("tom",19)
    stu2 = Student("tom",19)
    stu3 = stu2
    print(id(stu1)==id(stu2),stu1 == stu2)  #False False
    #注意这里stu1和stu2的值是不等的,虽然初始化创建对象格式一样。
    print(id(stu2)==id(stu3),stu2 == stu3)  # True True
    

      关于is

    1.is成立的前提要是内容相同,内存中地址相同
    st1 ='aaaaa'
    st2 = 'bbbbb'
    st3 = 'bbbbb'
    st4 = st3
    print(st1 is st2, st2 is st3,st3 is st4)#False True True
    print(id(st1),id(st2),id(st3),id(st4))
    

     

     以上两题涉及到对象,用is

    3.类型判断用isinstance,不用type

    type()不会认为子类是一种父类类型。isinstance()会认为子类是一种父类类型。

    class Foo(object):
        pass
    
    
    class Bar(Foo):
        pass
    
    if __name__ == '__main__':
        print(type(Foo()) == Foo)
        print(type(Bar()) == Foo)
        print(isinstance(Foo(), Foo))
        print(isinstance(Bar(), Foo))
    

      

    4.对子类继承的变量,要显式定义和赋初值

    class A(object):
        x = 1
    class B(A):
        pass
    class C(A):
        pass
    
    if __name__ == '__main__':
        B.x = 2
        print(A.x, B.x, C.x)
    

      

    如果希望类C中的x不引用自A类,可以在C类中重新定义属性x,这样C类就不会引用A类的属性x了,它们之间值的变化就不会相互影响了

    5. 赋值、浅拷贝和深拷贝

    • =: 跟原对象完全相同,原对象改了啥,新对象也改了啥;
    • deepcopy: 原对象改了啥,新对象都不变
    • copy: 列表的列表会被修改

     

     copy浅拷贝:拷贝一个对象,但是对象的属性还是引用原来的,对于可变类型,比如列表和字典,只是复制其引用。基于引用所作的改变会影响到被引用对象。只要原来的对象改变,被浅拷贝的就会改变。

    deepcopy深拷贝:创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用。外围和内部元素都是拷贝对象本身,而不是引用。原来的对象改变了,不会影响到新的深拷贝的。

     注意:对于数字,字符串和其他原子类型等,没有被拷贝的说法。如果对其重新赋值,也只是新创建一个对象,替换掉旧的而已。使用copy和deepcopy时,需要了解其使用场景,避免错误。

     运行结果:

    运行结果:

     6. 字符串处理,字符集

     7. 正则表达式的使用

    7.1 re.match()

    尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

    7.2 re.search()

    扫描整个字符串并返回第一个成功的匹配

    7.3 re.sub()

    替换字符串中的匹配项。
    re.sub(pattern, repl, string, count=0, flags=0)

      • pattern : 正则中的模式字符串。
      • repl : 替换的字符串,也可为一个函数。
      • string : 要被查找替换的原始字符串。
      • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
      • flags : 编译时用的匹配模式,数字形式。

    7.4 re.group()

    re.group(0)与re.group()相同返回全部字符串,1以后才是re.groups()中的各个组。

    import re
    
    m = re.match('(www)-(d?)', 'abc-123')
    sentence = 'we are humans'
    matched = re.match(r'(.*) (.*) (.*)', sentence)
    if __name__ == '__main__':
        print(m.group())   # abc-1
        print(m.groups())   # ('abc', '1')
        print(m.group(0))   # abc-1
        print(m.group(1))   # abc
        print(m.group(2))   # 1
    
        print(matched.group())  # we are humans
        print(matched.groups())  # ('we', 'are', 'humans')

    7.5 re.split()

    split 方法按照能够匹配的子串将字符串分割后返回列表。Python自带的split函数只能指定一个分割符,需要使用多个分割符时,可以使用re.split()。

     

     7.6 re.findall()

    在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。注意: match 和 search 是匹配一次 findall 匹配所有

     

    import re
    line = "Cats are smarter than dogs"
    # .* 表示任意匹配除换行符( 、 )之外的任何单个或多个字符
    matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)

    if matchObj:
    print("matchObj.group() : ", matchObj.group())
    print("matchObj.groups() : ", matchObj.groups())
    print("matchObj.group(0) : ", matchObj.group(0))
    print("matchObj.group(1) : ", matchObj.group(1))
    print("matchObj.group(2) : ", matchObj.group(2))
    print("matchObj.group(3) : ", matchObj.group(3))
    else:
    print("No match!!")

      

  • 相关阅读:
    CocosIDE导出Android APK的注意事项
    C++14尝鲜:Generic Lambdas(泛型lambda)
    silverlight调用WebService传递json接收绑定数据
    解决考试系统高并发数据载入不对问题
    汇编入门学习笔记 (九)—— call和ret
    Java SerialPort SDK
    how tomcat works 总结 二
    linux下多线程的调试
    垃圾回收GC:.Net自己主动内存管理 上(二)内存算法
    HDU-4973-A simple simulation problem.(线段树)
  • 原文地址:https://www.cnblogs.com/GumpYan/p/14139898.html
Copyright © 2011-2022 走看看