zoukankan      html  css  js  c++  java
  • day3----编码-集合-深浅copy-文件操作-函数初识

    本文档主要内容

    一 编码

    二 集合

    三 深浅copy

    四 文件操作

    五 函数初识

    首先,我们来看看两个字符串的比较

    打开cmd,进入dos界面
    
    >>>a='xingchen@'
    
    >>>b='xingchen@'
    
    >>>print(a==b)    结果为 True
    
    >>>print(a is b)    结果为 False
    
    上面的两种结果不一样为什么?
    View Code

    这里我们引入id命令,用来测试内存地址

    >>> print(id(a))
    2138501550128
    >>> print(id(b))
    2138501550184 #可以看出内存地址不一样
    View Code

    自此:== 比较的是值,而is比较的是内存地址

    进行第二个实验让 a='xingchen'  b也是b='xingchen'  结果两个都是True

    为什么?

    小数据池:在str和int中存在这样一个东西,它叫小数据池,即使存在100个这样的变量,在一定范围内,他们都指向同一个内存地址

         存在的意义:节省内存

    什么样的范围:对于int  -5 ---- 256 

           对于 str:1 不能含有特殊字符,2 单个元素*int 不能超过21

            例如:
              >>> i='a'* 20
              >>> i1='a' * 20
              >>> print(id(i),id(i1))
              2138501554296 2138501554296 #这里是一样的
              又如:
              >>> i='a'* 21
              >>> i1='a' * 21
              >>> print(id(i),id(i1))
              2138501554368 2138501554440 #这里就不一样了
    View Code

    First -------编码

    1.1  ascii

    包含数字,字母,特殊字符,它只有两种表示形式0和1,八个这样的二进制被称为一个字节(byte),
    
    ascii一共规定了128个字符的编码,这128个字符只占了这个字节的后七位,最前面的一位为0
    View Code

    1.2 unicode

    万国码,unicode字符集被简成为ucs。
    
    unicode起初是用两个字节表示一个字符,后来规定一个字符使用的3个或四个字节表示,
    
    这里就产生了问题:无论是简单的英文字符还是复杂的其他字符都用三或四个字节表示,对于存储来说造成了极大浪费,(一个中文使用四个字节表示)。
    View Code

    1.3 utf-8:

    utf-8是unicode的一种实现方式,其他还有utf-16和utf-32;
    
    它采用变长的编码格式,根据情况,可以使用1-4个字节表示,一般英文字符就用一个字节表示,欧洲语言使用两个字节表示,(中文使用三个字节表示)。
    View Code

    1.4 gbk

    中国大陆制订的,等同于ucs的新的中文编码扩展国家标准,可以表示简体字和繁体字,兼容gb2312
    View Code 

    **下面:Unicodeutf-8gbk,每个编码英文,中文,分别用几个字节表示。

          英文              中文
    
    unicode:   4       4
    
    utf-8:     1       3
    
    gbk:     1       2
    View Code

    其他:

    1 不同编码之间的二进制是不能互相识别的
    2 对于文件的存储以及传输,不能是unicode的编码(占内存多)。

    1.5 bytes和str

    在python3.x版本中,有两种类型的字符比较类似

    bytes:str拥有的功能,它也有,内部编码方式可以设定,非unicode,可能是utf-8,可能是gbk,可能是gb2312
    str(字符串):内部编码方式是unicode,所以不能直接用于文件的存储和传输
    str如果要存储: str 转化成--->bytes ---->用于存储和传输
    为什么要存在str---因为bytes显示出来的中文没办法识别,只有英文可以,bytes的类型前面有个b,例如b'abcd'

    str ---> bytes 使用encode 编码

    例如:    s1='xingchen'
        s2='中文'
    b1=s1.encode('utf-8')
    b2=s1.encode('gbk')
    b3=s2.encode('utf-8')
    b4=s2.encode('gbk')
    print(b1,b2) --->结果为:b'xingchen'    b'xingchen'   b1和b2看着结果一样却是不同的编码
    print(b3,b4) ----》结果为:b'xe4xb8xadxe6x96x87'      b'xd6xd0xcexc4' 中文就看出区别了
    View Code

    bytes --->str 使用decode 解码
    例如:b1.decode('utf-8')      b2.decode('gbk')

    utf-8要向转化成gbk的编码格式:utf-8首先转化成utf-8的bytes类型,再转化成gdk的bytes类型,如果想转化成str的gdk再使用decode

    例如:

    例子1:
    s='中国' #utf-8的str类型
    b=s.encode('gbk') #gbk的bytes类型
    c=b.decode('gbk') #转化成str的gbk unicode
    print(b) #结果为 b'xd6xd0xb9xfa'
    print(c) #结果为 中国
    
    例子2:
    s2='中文'
    d=s2.encode('gbk').decode('gbk')
    d1=d.encode('gbk') #转化成gbk的bytes类型,查看编码格式
    e=s2.encode('utf-8').decode('utf-8')
    e1=e.encode('utf-8') #转化成utf-8的bytes类型,查看编码格式
    print(d,d1)
    print(e,e1)
    View Code

    pycharm上面使用的是str类型也即是unicode编码,如果从其他地方传过来的文件是utf-8的话,先encode为utf-8的unicode类型,转化成gbk的话再decode('gbk')就好了

     pycharm上面的字符串本身就是unicode编码,因此可以直接转化其他编码的bytes类型,例如:str.encode('utf-8')   又如: str.encode('gbk')

    ********************************所以utf-8的bytes类型转化成gbk的bytes类型 s.encode('utf-8').decode('gbk') 。反之亦然************************************回到页头************************************************

    Second ----集合

    set1={}
    1要求它里面的元素,是可哈希的,str tuple int bool,元素不重复,无序
    集合本身是不可哈希的
    2 功能:关系测试,去重
    例如:
      set1={'a','b','c','d','a'}
      print(set1) #结果为{'b', 'c', 'a', 'd'},再刷新就变成{'a', 'b', 'c', 'd'} #表明是无序的

    #将一个列表去重

      l=[1,2,1,3,3,4,5,4]
      print(set(l)) ---》{1, 2, 3, 4, 5}
      print(list(set(l))) --》[1, 2, 3, 4, 5]
    View Code

    集合的--增

      set={'a','b','c'}
      set.add('d')
      print(set)
    View Code

    集合的--删

      set1={1,2,3}
      set.update(set1)
      print(set) #结果为 {1, 'c', 'd', 2, 3, 'b', 'a'}
      set.pop() #随机删除因为无序性
      print(set)
      set.remove('a') #按照元素删除,不存在会报错
      print(set)
      set.clear()
      print(set) # 结果 set()
      del set 只能删除整个集合,del不能切片删除
    View Code

    #没有改,下面是查
    集合的---查
    # 使用for循环
      for i in set:
      print(i)
    不能使用in查

    集合的一些用法:
    #交集

      set1={1,2,3,4,5}
      set2={4,5,6,7,8}
      print(set1 & set2)
      print(set1.intersection(set2))
    View Code

    #并集
      print(set1 | set2)
      print(set1.union(set2))
    #差集,前面独有的元素

      print(set1 - set2)
      print(set2-set1)
      print(set1.difference(set2))
    View Code

    #反交集
      print(set1 ^ set2)
      print(set1.symmetric_difference(set2))
    #子集
      set1={1,2,3}
      set2={1,2,3,4,5}
      print(set1 < set2)
      print(set1.issubset(set2))
    #超集
      print(set2>set1)
      print(set2.issuperset(set1))
    #不可变的集合
      print(frozenset(set1)) ---》frozenset({1, 2, 3})

    Third ---深浅copy                                                                   回到页头

    s1=[1,2,3]
    s2=s1 #赋值,共用一个空间,无论多少层是一样的,一个改变,另外一个也会改变
    s1.append(666)
    print(s1,s2) ----》[1, 2, 3, 666] [1, 2, 3, 666]
    
    s1=[1,2,3]
    s2=s1.copy() #浅copy
    s1.append(666)
    print(s1,s2) ---》[1, 2, 3, 666] [1, 2, 3]
    
    s1=[1,2,3,[11,22]]
    s2=s1.copy()
    s1[-1].append(666)
    print(s1,s2) ---》[1, 2, 3, [11, 22, 666]] [1, 2, 3, [11, 22, 666]]
    View Code

    *******所以浅copy第一层各自独立,从第二层开始,共用一个内存地址*****

    import copy
    s1=[1,2,3,[11,22]]
    s2=copy.deepcopy(s1)
    s1[-1].append(666)
    print(s1,s2) --》[1, 2, 3, [11, 22], 666] [1, 2, 3, [11, 22]]
    View Code

    深copy无论多少层,都是相互独立的

    #切片:浅copy

      s1=[1,2,3,[11,22]]
      s2=s1[:]
      # s1.append(666) #结果为 [1, 2, 3, [11, 22], 666] [1, 2, 3, [11, 22]]
      s1[-1].append(666) #结果为[1, 2, 3, [11, 22, 666]] [1, 2, 3, [11, 22, 666]]
      print(s1,s2)
    View Code

    模拟tail -f命令

    #tail -f access.log
    # import time
    # with open(r'xxxxx','rb') as f:
    #     f.seek(0,2)
    #     while True:
    #         line=f.readline()
    #         # print('===>',line)
    #         if line:
    #             print(line.decode(),end='')
    #         else:
    #             time.sleep(0.05)
    tail -f

    Fourth---文件操作

    文件路径:path
    编码方式:encoding
    操作方式:mode: 读,写,读写,写读,追加,改。。。
    执行流程:1打开文件,产生文件句柄 2 对文件句柄进行操作 3关闭文件句柄

    f1=open(r'b.txt',encoding='utf-8',mode='r')
    print(f1.read())
    f1.close()

    f1文件句柄,open()调用的内置函数,内置函数调用的系统内部open
    r'b.txt' 表示文件路径转义,一般加r,或者加一个/转义路径碰到的问题
    mode='r' 其中r的模式是默认的

    read() 读取文件中的全部内容
    read(n)读取一部分内容

    对于mode模式,有两种情况

    mode='r'

    r模式:read(n) 按照字符读取n个字符

    rb模式:以bytes方式读取,read(n)按照字节读取n个字节,一个中文一般要读取三个字节,要不然解码的时候会报错

    readline() 每次读取一行
    readlines() 读取全部内容,但是处在一行,放在一个列表中,以回车( )为分隔
    for循环读取:每次读取一行

    下面是举例说明

    写:w
    没有文件,新建文件写入内容,
    有文件的话--》先清空内容,再写入新内容

    f1=open('c.txt',encoding='utf-8',mode='w')
    f1.write('呵呵 kjdf')
    f1.close()
    View Code

    图片的读取与写入,实现了新复制的图片2 #图片必须使用bytes的类型读取

      f1=open('1.jpg',mode='rb')
      content=f1.read()
      f2=open('2.jpg',mode='wb')
      f2.write(content)
      f1.close()
      f2.close()
    View Code

    追加 a
    没有文件,创建文件,类似于w
    有文件,在最后追加内容

    r+ 读写模式,先读后写,如果先写后读的话,将写的内容覆盖原文件一部分内容,按照字节替换,如果写的内容不是中文字节的3倍将报错,这里指utf-8编码

    f1=open('b.txt',encoding='utf-8',mode='r+')
    print(f1.read())
    f1.write('666') #里面只能加入字符串类型的字符
    f1.close()
    
    f1=open('b.txt',encoding='utf-8',mode='r+')
    # print(f1.read())
    # f1.write('666') #里面只能加入字符串类型的字符
    f1.write('a') #报错
    print(f1.read())
    f1.close()
    View Code

    w+先写后读,有文件将清空内容,再写入,此时光标在最后,读的是空内容

    a+ 先追加再读

    操作方法:read readline readlines write
    其他操作方法:readable是否可读 writable是否可写
    print(f1.tell()) 打印出光标的位置,按照字节显示数字
    f1.seek(12) 任意调整光标的位置 --》按照字节移动
    f1.seek(0,2) 光标调整到最后
    f1.seek(0) 光标调整到开头

    f1=open('b.txt',encoding='utf-8',mode='r')
    f1.read(3) #按照字符读取
    print(f1.tell()) #打印光标的位置是按照字节
    f1.close()

    f1.truncate(n) 按照字节对源文件进行截取,必须是在 a或 a+,或者r+模式,清空文件内容再将截取的内容放入文件

      f1=open('b.txt',encoding='utf-8',mode='a+')
      f1.truncate(3) #截取了三个字节
      f1.close()
    View Code

    with open('文件路径',encoding='模式') as f1 不用主动关闭文件句柄,可以打开多个文件
    with open('c.txt',encoding='utf-8') as f1,
    open('b.txt',encoding='utf-8',mode='w') as f2:
    content=f1.read()
    f2.write(content)
    清空b.txt中的内容,并将c.txt的内容复制到b.txt中

    文件的修改:
    1 以读的模式打开原文件,以写的模式打开一个新文件(这个文件可以事先不存在)
    2 将原文件读出,并按要求修改,并将修改后的内容写入新文件
    3 删除原文件
    4 将新文件重命名为原文件
    例如:

      import os
      with open('b.txt',encoding='utf-8') as f1,
      open('b.bak',encoding='utf-8',mode='w')as f2:
      for line in f1:
      new_line=line.replace('xingchen','AA')
      f2.write(new_line)
      os.remove('b.txt')
      os.rename('b.bak','b.txt')
    View Code

     例子:文件一次读两行,区别单双行

    with open('test-test','r') as f:
       content=f.readlines()
       p=0
       q=2
       print(len(content))
       while True:
          i=content[p:q]
          p = p + 2
          q = q + 2
          x,y=i[:]
          print(x.split()[0],y.split()[0])
          if q==len(content)+2:
             break
          elif q==len(content)+1:
             i=content[-1]
             print(i)
             break

    Fifth-----函数初识

    def 函数名():
    函数体
    出现return的话,return后面的内容不会执行
    **return 等同于 return None 一般None省略

    return的返回值有两种:
    1 return 可以返回单个值
    2 return 可以返回多个值多个值,会将多个值放入一个元组中,将元组返回给函数的执行者
    例如:

      def func1():
        print(111)
        print(2222)
        return 666 ,'xingchen',[1,2,3]
      ret=func1()
      print(ret)
    View Code

    实参角度
    位置参数: 必须一一对应
      def func1(a,b,c):
        print(a,b,c)
    func1(1,2,'xingchen')

    def max(a,b): return a if a>b else b #比较大小的函数

    关键字传参:必须一一对应
      def func2(a,b):
        print(a,b)
    func2(b=2,a=3)

    混合参数:(位置参数和关键字参数)关键字参数必须在位置参数后
      def func2(a,b,c,d):
        print(a,b,c,d)
    func2(1,2,d=3,c=5)

    形参角度
    位置参数。按顺序一一对应

    默认参数。默认参数在位置参数的后面

    def login(name,sex=''):
      with open('register',encoding='utf-8',mode='a') as f1:
      f1.write('{},{}
    '.format(name,sex))
    
    while True:
    name=input('姓名: ').strip()
    if '1' in name:
      login(name)
      else:
      sex=input('性别: ').strip()
    login(name,sex)
    View Code

    动态参数,*args, **kwargs #函数定义的时候,*代表聚合,**表示关键字参数放入一个字典
    args:所有的位置参数,放在一个元组中
    kwargs:所有的关键字参数,放在一个字典中

      def func3(*args,**kwargs):
        print(args)
        print(kwargs)
    func3(1,2,3,'alex',c=6,name='wu',age='21')
    
    结果为:
    (1, 2, 3, 'alex')
    {'c': 6, 'name': 'wu', 'age': '21'}
    
    def func3(*args,**kwargs): #函数定义的时候*代表聚合
      print(args)
      print(kwargs)
    
    func3(*[1,2,3],*(22,33)) #函数执行的时候,*代表打散,也即是将列表或者列表亦或元组打散为单个的元素
    结果为:(1, 2, 3, 22, 33)
    {}
    
    func3(**{'name':'xingchen'},**{'age':23})
    结果为
    ()
    {'name': 'xingchen', 'age': 23}
    View Code

    形参的顺序:位置参数 *args,默认参数,**kwargs
    def func5(a,b,*args,sex='男',**kwargs):
      print(a,b)
      print(args)
      print(sex)
      print(kwargs)

                                  回到页首

  • 相关阅读:
    Java中的引用
    JVM参数调优
    GCRoots
    JVM体系结构
    死锁编码及定位分析
    线程池(Java中有哪些方法获取多线程)
    Synchronized和Lock的区别
    阻塞队列BlockingQueue
    CountDownLatch/CyclicBarrier/Semaphore
    浅谈二分
  • 原文地址:https://www.cnblogs.com/mmyy-blog/p/9084256.html
Copyright © 2011-2022 走看看