zoukankan      html  css  js  c++  java
  • 5、垃圾回收机制与用户交互以及运算符

    一、垃圾回收机制

    1.1、什么是垃圾回收机制?

        垃圾回收机制是Python解释器自带的一种机能,专门用来回收不可用的变量值所占用的内存空间。

    1.2、为什么要有垃圾回收机制?

        在程序的运行中,会申请大量的内存空间,造成内存溢出,导致程序崩溃。因此管理内存是一件繁杂的事,所以Python解释器自带的垃圾回收机制能让程序员从中脱离出来。

    1.3、垃圾回收机制什么使用?

        因为这是在Python解释器后台中执行的,因此不需要去操控他。

    二、理解GC垃圾回收机制原理

    2.1、堆区和栈区

      在定义变量时变量名、变量值都是需要储存的。分别对应在内存中的两个地方栈区以及堆区。

      变量名以及值内存地址存放在栈区

      变量值存放在堆区,垃圾清理的就是堆区。

    2.2、直接引用和间接引用

      直接引用指的是变量名直接通过内存地址,由栈区引用到堆区。

      例如:a=[10,20]

      间接引用指的是变量名由栈区引导到堆区后,再通过下一步引用找到对应的堆区。

      例如:a=[b,20]

         b=30

      这里a会有一个存放在内存的堆区,而后会再找到20和30的堆栈。

    2.3垃圾回收机制原理介绍

      Python上的GC模块采用“引用计数”来跟踪和回收垃圾;在使用引用计数的基础上,还可以使用“标记清除”解决容器对象可能出现的循环引用问题;并且通过“分代回收”以空间换区时间的方式进一步提高垃圾回收的效率。

     2.3.1、引用计数

      引用计数是变量值被变量名引用次数的统计。

      例如:a = 1,b=a时,1这个值就被引用两次了。这就是引用次数的增加。

       当:a=2时,1这个值就只剩b引用了,这就是引用次数的减少。

      如果引用次数为0时,就会清除堆栈里面的变量值。

     2.3.2、引用计数问题一:循环引用

      引用计数有一个致命的问题即循环引用(也称交叉引用)

      例如:当断开a1,以及a2的关联时(del a1,del a2),a1与a2的值还在互相引用着,这就会导致引用计数不为0,无法清除。

    a1 = [11, ]
    a2 = [22, ]
    a1.append(a2)
    print(a1)    #[11, [22]]
    a2.append(a1)
    print(a2)    #[22, [11, [...]]]

      然而,由于断开了a1,与a2的关联,所以也找不到这两个对应的值。造成内存永远不会被释放所以python引用了“标记-清除”以及“分代回收来解决这个问题

     2.3.2、解决方案:“标记-清除”

      “标记-清除”的做法是找到所有栈区里面所有变量名对应堆区的变量值进行标记,当内存空间被耗尽时,停止程序,清除所有堆区未被标记的变量值。从而解决引用计数带来的循环计数问题。

     2.3.2、引用计数问题二:效率问题

      基于垃圾回收机制每次回收内存,需要将所有对象的引用计数全部扫一遍,十分的消耗时间,因此使用空间换取时间的方法。即分代回收。

     2.3.4、解决方案:分代回收

      分代回收的核心是通过多次的扫描,部分变量还是没有被清零,因此决定将他们默认为常量,并且减少对这部分变量值的扫描。从而节省时间。

    三、Python语法之用户交互

    3.1、什么是用户交互

      用户交互就是人往计算机中输入数据,计算机根据设定好的结果输出数据。

    3.2、为什么需用户交互?

      希望计算机能够和人一样进行交流。

    3.3、怎么和用户进行交互

      交互的本质就是输入以及输出。

    3.3.1、输入input

      username=input('请输入你的账号:')   # 请输入你的账号:

      Python3中,所有输入的值都会变成字符串类型。

    3.3.2、输出print

      只输出一个值:

      print('hallo world')    #  hallo world

      输出多个值:

      print('a,b,c')      # a,b,c

    3.3.3、格式化输出

    3.3.3.1、什么是格式化输出

      将一段字符里面的某些内容替换掉之后输出,称之为格式化输出。

    3.3.3.2、为什么要有格式化输出

      我们经常会输出一些固定格式的内容,例如:亲爱的XXX你好。我们需要做的就是将XXX替换掉。

    3.3.3.3、格式化输出怎么使用

      通常使用占位符%d以及%s。%d只能代替数字,%s可以代替任何类型。

    3.3.3.3.1、字符串类型使用格式化输出

      例如:res='my name is %s my age is %s'%(egon,18)

    3.3.3.3.2、字典类型使用格式化输出

      例如:res=‘my name is %(name)s my age is %(age)s’ %{'name':'egon','age':18}

    3.3.3.3.3.1、使用字符串str.format:兼容性好  建议使用

      例如:res='my name is {} my age is {}'.format('egon',18)

      也可以:res='my name is {0}{0}{0} my age is {1}{1}'.format('egon',18)

    3.3.3.3.3.2、使用字典dict.format

      例如:res='my name is {name} my age is {age}'.foemat(name='egon',age=18)  #format()内加的是变量。

    3.3.3.3.4 填充与格式化

    先取到值,然后在冒号后设定填充格式:[填充字符][对齐方式][宽度]
    *<10:左对齐,总共10个字符,不够的用*号填充
    print('{0:*<10}'.format('开始执行')) # 开始执行******

    *>10:右对齐,总共10个字符,不够的用*号填充
    print('{0:*>10}'.format('开始执行')) # ******开始执行

    *^10:居中显示,总共10个字符,不够的用*号填充
    print('{0:*^10}'.format('开始执行')) # ***开始执行***
    3.3.3.3.5精度与进制

    print('{salary:.3f}'.format(salary=1232132.12351)) #精确到小数点后3位,四舍五入,结果为:1232132.124
    print('{0:b}'.format(123)) # 转成二进制,结果为:1111011
    print('{0:o}'.format(9)) # 转成八进制,结果为:11
    print('{0:x}'.format(15)) # 转成十六进制,结果为:f
    print('{0:,}'.format(99812939393931)) # 千分位格式化,结果为:99,812,939,393,931

    3.3.3.3.6、f   :   #python3.5后才推出

    x = input('your name: ')
    y = input('your age: ')
    res = f'我的名字是{x} 我的年龄是{y}'
    print(res)

    四、运算符

    4.1、算数运算符

      Python在支持算数运算符上与数学上运用的符号是一致的。

    假设变量:a=10,b=20

     

    4.3、比较运算符

      通常用来对两个值进行比较,返回的值为Ture或者Flase.。

     4.3、赋值运算符

      赋值=运算符中除了=号以外,还有增量赋值、链式赋值、交叉赋值、解压赋值。这些赋值方式可以让代码看的更加精简。

    4.3.1、增量赋值

     4.3.2、链式赋值

      可以将一个值同时赋值给多个变量名,例如:

      a=1

      b=a

      c=b

      可以写成a=b=c=1

    4.3.3、交叉赋值

      可以将两个变量对应的变量值进行交换。例如:

      m=2

      n=3

      l=m

      m=n

      n=l

      可以写成:m,n=n,m

    4.3.4、解压赋值

      可以将列表中多个值取出来赋值给多个变量名,例如:

      number=[1,2,3,4,5,]

      print(number[0])

      print(number[1])

      print(number[2])

      print(number[3])

      print(number[4])

      可以直接写成a,b,c,d,e=number

            print(number)

      在赋值的多个变量名数量无法与列表中的变量名数量一致时,可以使用:

      a,b,c,*_=number       #只取前面三个值

      *_,a,b,c=number    #只取后面三个值

      字符串、字典、元组、集合类型都支持解压赋值



  • 相关阅读:
    面向消息的持久通信与面向流的通信
    通信协议
    [1]序章,基本
    深拷贝和浅拷贝
    堆/栈 内存管理相关
    C++的四种cast(显示类型转换)
    智能指针相关
    C++对象模型:单继承,多继承,虚继承
    HTTP/TCP
    [读书笔记] 为什么绝不在构造/析构函数中调用virtual函数
  • 原文地址:https://www.cnblogs.com/jingpeng/p/12423730.html
Copyright © 2011-2022 走看看