zoukankan      html  css  js  c++  java
  • python基础之小数据池、代码块、编码

    一、代码块。
    if True:
      print(333)
      print(666)

    while 1:
      a = 1
      b = 2
      print(a+b)

    for i in '12324354':
      print(i)

    虽然上面的缩进的内容都叫代码块,但是他不是python中严格定义的代码块。
    python中真正意义的代码块是什么?

    块是一个python程序的文本,他是作为一个单元执行的。
    代码块:一个模块,一个函数,一个类,一个文件等都是一个代码块。

    而对于一个文件中的两个函数,也分别是两个不同的代码块:

    def func():
      print(333)
    class A:
      name = 'xiaojing

    交互模式下,每一行是一个代码块。

    什么叫交互方式?就是咱们在cmd中进入Python解释器里面,每一行代码都是一个代码块
    >>> i1 = 520  可以理解为这一行在一个文件中。
    >>> i2 = 520  可以理解为这一行在另一个文件中。

    二、id is ==

    在Python中,id是什么?id是内存地址,== 是比较的两边的数值是否相等,而 is 是比较的两边的内存地址是否相等。

    如果内存地址相等,那么这两边其实是指向同一个内存地址。

    name = 'shuaige'                   # 赋值
    print('shuaige' == 'shuaige')   # 数值相同
    name = 'abc123'
    name1 = 'abc123'
    print(id(name),id(name1)) # 2370269674608 2370269674608
    在内存中id都是唯一的,如果两个变量指向的值的id相同,就证明他们在内存中是同一个。
    is 判断的是两个变量的id值是否相同。
    如果is是True, == 一定是True。== 是True,is不一定是True

    三、小数据池(缓存机制,驻留机制)

    小数据池的应用的数据类型: 整数,一定规则的字符串,bool值

    小数据池是python对内存做的一个优化:
    python将 -5 ~256 的整数,以及一定规则的字符串,bool值,进行了缓存,就是提前在内存中创建了池(容器),
    在这些容器里固定的放了这些数据。
    为什么这么做???
    1,节省内存。
    2,提高性能与效率。

    int:对于整数来说,小数据池的范围是 -5~256 ,如果多个变量都是指向同一个(在这个范围内的)数字,他们在内存中指向的都是一个内存地址。
    i1 = 110
    i2 = 110

    i3 = 110

    一定规则的字符串?

    1,字符串的长度为0或者1,默认都采用了驻留机制(小数据池)

    2,字符串的长度>1,且只含有大小写字母,数字,下划线时,才会默认驻留。

    3,用乘法得到的字符串,分两种情况。

         3.1 乘数为1时:仅含大小写字母,数字,下划线,默认驻留。

          3.1.2含其他字符,长度<=1,默认驻留。

     

        3.1.3含其他字符,长度>1,默认驻留

    3.2 乘数>=2时:仅含大小写字母,数字,下划线,总长度<=20,默认驻留。

     4,指定驻留。

    复制代码
    from sys import intern
    a = intern('hello!@'*20)
    b = intern('hello!@'*20)
    print(a is b)
    #指定驻留是你可以指定任意的字符串加入到小数据池中,让其只在内存中创建一个对象,多个变量都是指向这一个字符串。
    复制代码

    四、代码块与小数据池的关系

    同样一段代码,为什么在交互方式中(cmd命令的终端)执行,和通过pycharm执行结果不同呢?

    复制代码
    # pycharm 通过运行文件的方式执行下列代码:
    i1 = 520
    i2 = 520
    print(i1 is i2)  # 结果为True
    通过交互方式中执行下面代码:
    >>> i1 = 520
    >>> i2 = 520
    >>> print(i1 is i2) #结果为False
    复制代码

    那为什么结果会不同呢?

    在同一个代码块中的变量(数字,字符串),初始化对象的命令时,首先会从小数据池中找,如果没有找到,它会将变量与值的对应关系放到一个字典中,
    同一个代码块中的其他变量遇到初始化对象的命令,他会先从字典中寻找,如果存在相同的值,他会复用,指向的都是同一个内存地址。

    所以,在pycharm中的两行变量赋值中(实际上在同一个代码块中的赋值):
    (如果这个变量不是数字或者字符串,那么值相同,地址也是不同的)

    s1 = 1000

    s2 = 1000

    print(s1 is s2)         #True

    而在cmd命令的终端中(交互模式),每一行都是一个代码块,因此在cmd命令的终端中,s1和s2是在不同的代码块,因此s1 is s2 是False

    l1 = [1,2]
    l2 = [1,2]
    print(id(l1),id(l2)) # 1745841050760 1745840183304
    print(l1 == l2)   # True
    print(l1 is l2)     # False


    在不同的代码块:初始化对象的命令时,首先从小数据池中寻找,如果在小数据池,那么地址相同,如果不在小数据池中,则创建新的地址。

    不同代码块中:

    复制代码
    def func():
        i1 = 1000
        print(id(i1))
    
    
    def func1():
        i2 = 1000
        print(id(i2))
    func()
    func1()
    # 一个函数是一个代码块,因此这里的i1的地址跟i2的地址不是同一个地址
    复制代码

    总结:
    同一代码块中:
    如果变量在小数据池,那么地址相同,
    如果不在小数据池,那么如果变量是数字或者字符串,也会复用地址,地址也相同,
    如果变量不是数字或者字符串,那么地址不同。

    不同一代码块中:
    如果变量在小数据池,那么地址相同,
    如果不在小数据池,那么地址不同。


    五、编码二
    ASCII: 字母,数字,特殊字符。
    A: 0000 0010
    B: 0000 0011
    unicode: 万国码,包含世界上所有的文字。
    创建之初:16位
    A :0001 0010 0000 0010
    中:0011 0010 0000 0110
    升级:32 位
    A :0000 0010 0100 0010 0000 0010 1000 0010 
    中:0001 0010 0010 0010 0000 0010 0010 0010
    缺点:浪费资源。


    对unicode 升级:utf-8:最少用8位表示一个字符。
    A :0000 0010     8位
    欧:0000 0010 0100 0010     16位
    中:0000 0010 0001 0010 0000 0010      24位

    GBK: 国标:字母,数字,特殊字符,中文。
    A :0000 0010     8位
    中:0000 0010 0001 0010    16位

    1, 编码之间不能互相识别。
    2, 网络传输,或者硬盘存储的010101,必须是以非uniocde编码方式的01010101.

    3,大环境python3x:
    str:内存(内部)编码方式为Unicode,因此python3中的字符串不能直接用于网络传输和硬盘存储,为了解决这个问题,就出现了bytes
    bytes:python的基础数据类型之一,他和str相当于双胞胎,str拥有的所有方法,bytes类型都适用。

    区别:
    英文字母:
    str:
    表现形式:s1 = 'xiaohei'
    内部编码方式:unicode


    bytes:
    表现形式:b1 = b'xiaohei'
    内部编码方式:非unicode

    中文:
    str:
    表现形式:s1 = '小黑'
    内部编码方式:unicode


    bytes:
    表现形式:b1 = b'xe5xb0x8fxe9xbbx91'
    内部编码方式:非unicode

    如何使用:
    你想将一部分内容(字符串)写入文件,或者通过网络socket传输,这样这部分内容(字符串)必须转化成bytes才可以进行。
    在平时的代码中,可以直接使用字符串。

    具体使用方法:encode编码 decode解码(bytes拥有str的所有方法)

    encode()不写参数,默认编码成utf-8

    str ---> bytes  encode 编码
    非中文可以使用encode(),也可直接在字符串前加一个 b 表示bytes
    s1 = 'xiaohei'

    b1 = b'xiaohei'     --->等于 b1 = s1.encode()
    b2 = b1.upper()

    print(s1, type(s1))

    print(b1, type(b1))
    print(b2, type(b2))

    中文只能使用encode()
    s1 = '小黑'
    b1 = s1.encode('utf-8')
    b2 = s1.encode('gbk')
    print(b1) # b'xe5xb0x8fxe9xbbx91'
    print(b2) # b'xd0xa1xbaxda'

     

    bytes ---> str decode  解码
    b1 = b'xd0xa1xbaxda'    #gbk的bytes
    s2 = b1.decode('gbk')        #对应用gbk的解码
    print(s2)

  • 相关阅读:
    MockMvc control层单元测试 参数传递问题
    @GetMapping和@PostMapping接收参数的格式
    获取 request 中用POST方式"Content-type"是"application/x-www-form-urlencoded;charset=utf-8"发送的 json 数据
    测试驱动开发实践—从testList开始
    深度解读
    深度解读
    3年不辭職!記住,在石頭上也要坐3年!(但也要区分5种不值得留的公司,12种留不住人才的公司)
    Configuring Your EMS Server or EMS Console Server on Windows/Linux
    XML 标准诞生 20 周年:这个世界,它无处不在
    通富微电石明达:成熟接班人也是先进生产力(执行力+判断力=抄底)
  • 原文地址:https://www.cnblogs.com/yidashi110/p/10092291.html
Copyright © 2011-2022 走看看