day04--垃圾回收机制、格式化字符串、基本运算符

一、垃圾回收机制详解


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

引入垃圾回收机制的意义:释放系统中一些无用的内存空间,防止内存溢出,降低程序崩溃的风险。

原理分析:

(1)使用“引用计数”来跟踪和回收垃圾;

(2)使用“标记-清除”来解决容器中存在的循环引用问题;

(3)通过“分代回收”的方式来提高垃圾回收的效率。

引用计数值:变量值被变量名关联的次数

x = 18
y =  x
z =  x
list_1 = [10,x]
dict_1 = {'age':x}
变量值13被引用的次数为5次
直接引用3次,间接引用2次
引用为地址传递,而非值传递,没有开辟新的内存空间

 分析一个例子

x = 10
list_1 = ['a','b',[1,2,3],x]    列表里存储的是['a'的内存地址, 'b'的内存地址, [1,2,3] 的内存     
                                          地址,10的内存地址]
x = 123
print(list_1)   >> ['a','b',[1,2,3],10]

 标记清除:主要是为了解决容器对象(list、set、dict、 clase、instance)引起的循环引用问题,这些容器对象都包含有对其他对象的引用。

关于变量的存储,在内存中有两块区域——栈区和堆区,栈区存储的是变量名和变量值内存地址的关联关系,堆区存储的是变量值,内存管理回收的就是堆区的内容

name_1 = 'egon', name_2 = 'tank'

当执行 name_1 = name_2 时,在内存中变化如下:

标记/清除算法的做法是当应用程序可用的内存空间被耗尽的时,就会停止整个程序,然后进行两项工作,第一项则是标记,第二项则是清除

#1、标记
标记的过程其实就是,遍历所有的GC Roots对象(栈区中的所有内容或者线程都可以作为GC Roots对象),然后将所有GC Roots的对象可以直接或间接访问到的对象标记为存活的对象,其余的均为非存活对象,应该被清除。

#2、清除
清除的过程将遍历堆中所有的对象,将没有标记的对象全部清除掉。

 分代回收

在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低

分代回收的核心思想是:在历经多次扫描的情况下,都没有被回收的变量,gc机制就会认为,该变量是常用变量,gc对其扫描的频率会降低

二、格式化字符串(%s、format、f-string)


1、%占位符

%s占位符:可以接收任意类型的值
%d占位符,只能接受数字
name = input('please enter the name:').strip()
height = int(input('please enter the height:').strip())
print('my name is %s , my height is %d' % (name,height))

2、str.format

(1)使用位置参数,按照位置一一对应
print('{} say {} is a good boy'.format('egon','tank'))
egon say tank is a good boy

(2)使用索引对应位置的值
print('{0} say {1} is a good boy, so many {2} like {1}'.format('egon','tank','girl'))
egon say tank is a good boy, so many girl like tank

(3)使用关键字参数或者字典
print('my name is {name}, my height is {height}'.format(height=187,name='tank'))
my name is tank, my height is 187

user_info = {'name':'tank','age':18}
print('The age of {name} is {age}'.format(**user_info))   使用**进行解包操作  
The age of tank is 184)填充与格式化字符: 先取到值,然后在冒号后设定填充格式:[填充字符][对齐方式][宽度]

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

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

# *^10:居中显示,总共10个字符,不够的用*号填充
print('{0:*^10}'.format('开始执行')) # ***开始执行***
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
View Code

3、f-strings(python3.5版本后出来的)

f-strings表示以f或者F开头的字符串,核心之处在于{}的使用

  • {}可以是变量名
    >>> name = 'egon'
    >>> age = 19
    >>> f'The age of {name} is {age}'
    'The age of egon is 19'
    >>> 
  • {}可以是任意合法的Python表达式
    可以为数学表达式
    print(f'{3/2%2}')   1.5
    
    可以是函数
    >>> def test(n):
            print('last year,the age of {name} is {age}'.format(name='tank',age=n))
            return n+1
    
    >>> print(f'this year the age of tank is {test(18)}')
    last year,the age of tank is 18
    this year the age of tank is 19
    >>> 
    
    可以使用对象的方法
    name = 'egon'
    >>> print(f'who is {name.upper()}')
    who is EGON
    >>> 
  • 在类中使用
    >>> class Person(object):
    ...     def __init__(self, name, age):
    ...         self.name = name
    ...         self.age = age
    ...     def __str__(self):
    ...         return f'{self.name}:{self.age}'
    ...     def __repr__(self):
    ...         return f'===>{self.name}:{self.age}<==='
    ... 
    >>> 
    >>> obj=Person('egon',18)
    >>> print(obj) # 触发__str__
    egon:18
    >>> obj        # 触发__repr__
    ===>egon:18<===
    >>> 
    >>> 
    >>> 
    >>> # 在f-Strings中的使用
    >>> f'{obj}'   # 触发__str__
    'egon:18'
    >>> f'{obj!r}' # 触发__repr__
    '===>egon:18<==='

 三、基本运算符

在计算机中,人们可以进行多种类型的运算操作,包括算数运算、比较运算、逻辑运算、赋值运算、成员运算、身份运算、位运算。
  •  算数运算符:+ - * / // ** %
    # 3+2=5
    # 3-2=1
    # 3*2=6
    # 3/2=1.5
    # 3%2=1
    # 3//2=1
    # 3**2=9
  • 比较运算
        等于(==)
        不等于(!= or <>)
         大于(>)
        小于(<)
        大于等于(>=)
        小于等于(<=)
  • 赋值运算
        =
        +=
        -=
        *=
        /=
        //=
        %=
        **=
    
  • 逻辑运算
    逻辑与(and):and两边式子的布尔值都为True,则为True,否则为False
    逻辑或(or):or两边式子的布尔值只要有一个为True,则为True
    逻辑非(!):将目标的布尔值取反 
    
    # 三者优先级: not>and>or
    #1、not与紧跟其后的那个条件是不可分割的
    #2、如果条件语句全部由纯and、或纯or连接,按照从左到右的顺序依次计算即可
    #3、如果语句中既有and也有or,那么先用括号把and的左右两个条件给括起来,然后再进行运算
    
    # 短路运算(偷懒原则):
    0 or 1              >> 1
    1 and 3            >>3
    0 and 2 and 3   >>0
    0 and 2 or 1     >>1
    0 and 2 or 1 or 4    >>1
    0 or False and 1   >> False
  • 身份运算
    #is比较的是id
    #而==比较的是值
    
    id相同,值一定相同;但是值相同,id不一定相同。
原文地址:https://www.cnblogs.com/surpass123/p/12422741.html