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!!")

  

原文地址:https://www.cnblogs.com/GumpYan/p/14139898.html