zoukankan      html  css  js  c++  java
  • Python知识总汇

    python2和python3 的差别  

    python2:
      print('abc')   print 'abc'   两种方式都是都可以
      range()        xrange()   生成器
      raw_input()  用户交互

    python3:
      print('abc')
      range()   生成器
      input()   用户交互

    其他知识:

     = 赋值

    == 比较值是否相等   

    is 比较,比较的是内存地址 

    id(内容) 打印该内容的内存地址

    小数据池:为了节省内存空间,数字和字符串在小范围内可共用一个对象

    1,数字,字符串有小数据池   
    数字小数据池的范围 -5 -- 256
    字符串:1,不能有特殊字符
         2,s*20 还是同一个地址,s*21以后都是两个地址
    i1 = 6
    i2 = 6
    print(id(i1),id(i2))         #两个id内存地址一样,属于小数据池
    i1 = 300
    i2 = 300
    print(id(i1),id(i2))        #两个id内存地址不一样,不属于小数据池

    2,剩下的 list dict tuple set 不具有小数据池

    l1 = [1]
    l2 = [1]
    print(l1 is l2)   ------>False

    深浅copy 

    a = [11,22]  b = [33,44]  c=[a,b]

     d = c:是将这个新的变量指向之前那个数据的内存地址,d,c的d is c --> Ture,内存地址一样,只是指向之前的内存地址。

    e = copy.copy(c)  # e和d的内存地址不一样,copy是开辟了一个新空间,但是e[0] ,e[1]的内存地址和c[0],c[1]一样,所以copy的方式只是开辟了一个新内存地址,里面的元素任然是指向之前的元素,就会随着之前的元素改变而改变,即为浅copy

    f = copy.deepcopy(c)   # f和c的内存地址不一样,f[0],f[1]和c[0],c[1]的内存地址也不一样,完全复制了一份数据,独立于之前的元素,即为深copy。

            浅copy,只对表层数据起作用,对嵌套的数据不起作,会随着嵌套内数据的改变而改变

    #没有嵌套的列表
    # l1 = [1,2,3]
    # l2 = l1.copy()
    # print(l1,l2)
    # print(id(l1),id(l2))   # l1和l2的内存地址不一样
    # l1.append('a') 
    # print(l1,l2)    #对l1操作不会影响l2的值  
    #嵌套的列表
    # l1 = [1,2,[4,5,6],3]
    # l2 = l1.copy()
    # 
    # print(l1,id(l1))     #1812439743240
    # print(l2,id(l2))     # 1812435321608   l1和l2的内存地址不一样
    # l1.append('a')
    # print(l1)     #[1, 2, [4, 5, 6], 3, 'a']
    # print(l2)     #[1, 2, [4, 5, 6], 3]
    # l1[2].append('a')
    # print(l1)    #[1, 2, [4, 5, 6, 'a'], 3]
    # print(l2)    #[1, 2, [4, 5, 6, 'a'], 3]
    # print(id(l1[2]))     #2236254917896
    # print(id(l2[2]))     #2236254917896   l1[2],l2[2]的内存地址相同
                                  #对列表l1里面嵌套的列表的数值进行操作会改变l2的值
    

      

            深copy,对于copy出来的内容完全独立,是一个不受父本影响的新的数据容器

    # import copy
    # l1 = [1,2,[4,5,6],3]
    # l2 = copy.deepcopy(l1)
    # print(l1,id(l1))    #[1, 2, [4, 5, 6], 3]  id: 1741159826824
    # print(l2,id(l2))    #[1, 2, [4, 5, 6], 3]   id:1741159827336
    # l1[2].append('a')
    # print(l1)      #[1, 2, [4, 5, 6, 'a'], 3]
    # print(l2)      #[1, 2, [4, 5, 6], 3]      深copy不会在受影响
    # l1 = [1,[1],2,3,4]
    # l2 = l1[:]              #为浅copy
    # print(l2)
    # l1[1].append('a')
    # print(l1)         #[1, [1, 'a'], 2, 3, 4]
    # print(l2)          #[1, [1, 'a'], 2, 3, 4]
    

      闭包:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包

    a = 1
    def outer(a):
        def inner():
            print(a)
        inner()
    outer(a)
    

      装饰器:一个函数需要扩展功能,但要遵循封闭开放原则,不能对原函数进行修改,装饰器的存在就是为了在不修改函数的调用方式和代码。就是对函数的装饰,使其在不被修改的原则下有新功能

    def wapper(func):                    #装饰器
        def inner(*args,**kwargs):  #可以接受任何的参数
            res = func(*args,**kwargs)
            return res                     #返回的是my_sum的结果
        return inner              #返回inner,切记不可写inner()
    @wapper      #语法糖   相当于  my_sum = my_sum(1,2)
    def my_sum(a,b):    #被装饰函数
        sum1 = 0
        sum1= a + b
        return sum1
    sum = my_sum(1,2)   #inner(1,2)
    print(sum)              
    

      装饰器固定模式:

    def wrapper(func):   #func == qqxing
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)   #被装饰的函数
            return ret
        return inner
    
    @wrapper        #qqxing = wrapper(qqxing)
    def qqxing():
        print(123)
    
    ret = qqxing()
    

      装饰器的进阶:

    带参数的装饰器:

    #带参数的装饰器需要嵌套三个函数,外层函数可以用来控制是否需要执行装饰器装饰函数的功能
    falg = True         #控制是否执行装饰器,False表示不执行
    def log_sum(falg):
        def wrappers_sum(func):
            global falg
            def inner(*args,**kwargs):
                global falg
                if falg:
                    print('----------------')
                    ret = func(*args,**kwargs)
                    print('----------------')
                    #falg = False    #多个函数用装饰器的时候,只让其使用一次,再一次功能中登陆账号后,后面再调其他函数时就不需要重新登陆
                    return  ret
                else:
                    ret = func(*args,**kwargs)
                    return ret
            return inner
        return wrappers_sum
    @log_sum(falg)  #log_sum(falg)  --->wrappers_sum   先执行log_sum(falg) 得到@wrappers_sum 就是一个装饰器
    def my_sum(a,b):
        sum = 0
        sum = a + b
        print('good')
        return sum
    print(my_sum(1,2))
    @log_sum(falg)
    def good():
        print('sss')
    good()
    

      

    多个装饰器装饰一个函数:

    #多个装饰器装饰一个函数
    # def wrapper1(func):
    #     def inner1():
    #         print('wrapper1 ,before func')
    #         ret = func()
    #         print('wrapper1 ,after func')
    #         return ret
    #     return inner1
    # def wrapper2(func):
    #     def inner2():
    #         print('wrapper2 ,before func')
    #         ret = func()
    #         print('wrapper2 ,after func')
    #         return ret
    #     return inner2
    # def wrapper3(func):
    #     def inner3():
    #         print('wrapper3 ,before func')
    #         ret = func()
    #         print('wrapper3 ,after func')
    #         return ret
    #     return inner3
    # @wrapper3
    # @wrapper2
    # @wrapper1
    # def f():
    #     print('in f')
    #     return '哈哈哈'
    # print(f())
    

      打印结果:

    wrapper3 ,before func
    wrapper2 ,before func
    wrapper1 ,before func
    in f
    wrapper1 ,after func
    wrapper2 ,after func
    wrapper3 ,after func
    哈哈哈
    

      迭代器:

              可迭代对象可以使用双下函数来变成一个迭代器。迭代器的优点是可以一个一个的拿出容器中的数据,且可以节约内存空间

              可迭代对象有  list tuple str set dict  

    list = [1,2,3,4]
    list1 = list.__iter__()   #将可迭代对象变为迭代器
    print(list1.__next__())   #一个一个去出容器中的数值
    

      迭代对象中有 __iter__函数

      迭代器中有__iter__和__next__函数

      可以使用dir(数据类型)来看它有哪些双下划函数  如里面有__iter__函数则说明该i数据类型是可迭代对象

      可以使用dir(数据类型)来看它有哪些双下划函数  如里面有__iter__和__next__函数则说明该i数据类型是可迭代器

      可迭代的对象就可以被for循环来遍历

    生成器:

    本质:就是一个迭代器

    优点:1.节省内存空间

       2.好操作,可以一个一个取值,不重复取值

    生成器函数:只要有yield关键字的函数就是一个函数表达式

    def good():   #good()为一个生成器函数
        yeild 'good'   #yield 返回值,与return一样,但是不会终止函数
    g = good() #调用生成器函数 ,返回一个生成器(g)

    生成器取值:

    print(g.__next__())   #一个一个的取出生成器的值,每次生成一个不占内存,且取过的值不再取不重复,如果取完了里面的值再次取会报错
    for i in g:
      print(i) #一次性取出全部的值
    a = list(g) #类型强制转换,将生成器中的值全部转换为列表元素,一次取完

      

      

    生成器表达式

    列表推导式:
    [每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] #遍历之后挨个处理
    [满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #筛选功能
    list1 = [i for i in range(10)]   #列表推导式,操作方便  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    list = (i for i in range(10) if i>=5)   #list为列表
    print(list) #[5,6,7,8,9]

     生成器表达式

    (每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型)    #遍历之后挨个处理
    (满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件) #筛选功能
    list = (i for i in range(10) if i>=5) #list为生成器
    list.__next__()  #5
    list.__next__()  #6
    list.__next__()  #7
    

      生成器的进阶: send的取值作用与__next__()一样,只是在获取下一个值的时候,给上一yield的位置传递一个数据

              ***不能直接再开头使用send取值,因为没有yield可以给赋值,回报错

              ***也不可以在最后用send,最后一个yield不可以接受赋值

    # 获取移动平均值
    # avg = sum/count
    # def average():
    #     sum = 0
    #     count = 0
    #     avg = 0
    #     while True:
    #         num = yield avg
    #         sum += num    # 10
    #         count += 1    # 1
    #         avg = sum/count
    #
    # avg_g = average()
    # avg_g.__next__()
    # avg1 = avg_g.send(10)
    # avg1 = avg_g.send(20)
    # print(avg1)
    

      

    #装饰器和生成器的获取移动平均值
    def wrappers(func):  #func  -->avg_func   该装饰器就是为了第一次使用send不用写__next__
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)      # ret是一个生成器
            ret.__next__()                  #使用send之前必须先使用__next__()
            return ret
        return inner
    @wrappers  #avg_func = wrappers(avg_func)
    def avg_func():
        sum = 0
        count = 0
        avg = 0
        while 1:
            num = yield avg
            sum += num
            count += 1
            avg = sum / count
    avg_g = avg_func()     #avg_g 是一个生成器  此时avg_func()是inner() 所以返回值为ret即一个生成器
    print(avg_g.send(10))   #10.0
    print(avg_g.send(20))   #15.0
  • 相关阅读:
    2017 ACM-ICPC西安网赛B-Coin
    Codeforces389D(SummerTrainingDay01-J)
    Codeforces672D(SummerTrainingDay01-I)
    VS2017.滚动条选项
    VS.自动调试
    ffmpeg.mp4.格式资料
    vs2017.unresolved external symbol __imp__fprintf&__imp____iob_func
    vs2017."const char *"的实参与"char *"的形参不兼容_goto跳过类型声明
    vue项目开发时怎么解决跨域
    vue奇怪的知识点又增加了
  • 原文地址:https://www.cnblogs.com/zbaby/p/11815627.html
Copyright © 2011-2022 走看看