@Pycharm 快捷方式


文章目录


  • Ctrl+Alt+L (代码格式化)
  • Ctrl+Alt+M (提取方法)
  • shift +enter 跳转到下一行
  • Ctrl + Shift + 方向键 移动代码
  • shift + tab 退一个 Tab 键
  • Ctrl + Q 查看函数的说明文档
  • Ctrl + F12 查看当前项目定义的函数的列表
  • Alt + Enter 提示错误信息
  • shift +F6 Pycharm 中替换功能

2021.03.04

(1)内存(RAM):存储计算机运行的数据
(2)计算机:高速计算的电子计算器,数值计算、逻辑计算、记忆存储。
(3)冯诺依曼体系:输入设备(键鼠扫)、输出设备(显打)、运算器、控制器、存储器。
(4)系统软件(建立计算机和人之间的联系)、应用软件(实现特定的功能)。
(5)编程语言:Java、Python、C、C#、Cpp
(6)应用领域:网络爬虫、人工智能、机器学习、数据分析、Web 开发、自动化运维、自动化测试等。
(7)Google 开源机器学习框架:TensorFlow
开源社区主推学习框架:Scikit-learn
百度开源深度学习框架:Paddle
(8)Python 缺点:运行速度慢
不适用 Python:性能要求比较高的场景:游戏引擎、底层开发。
(9)爬虫:爬取关键信息,获取感兴趣内容。
(10)TIOBE 2021 02 2021.02 编程语言排行榜
(11)基础、流程控制、数据序列、函数、文件操作、面向对象、模块 / 包 / 异常。
(12)解释型:解释器读取一段,解释执行一段。
编译型:通过编译器将程序转化为二进制机器码执行
(13)Python 解释器:CPython(官方版解释器,用 C 写的)、IPython(内核 CPython,外观)、PyPy(动态编译)、Jython(把 Python 语言编写成 Java 的字节码文件)、ironPython(编译成.Net 字节码文件)
(14)IDE(集成开发环境):代码提示、命令简化、debug 调试 。例如 Pycharm
(15)注释:单行注释(#(习惯:# 后加一个空格) ctrl + /)、多行注释(’’‘Python’’' 或者 ""“Python”"")
Ctrl+Alt+L (代码格式化)
(16)变量:存储数据的内存,内存的别名
(17)变量命名规则:大驼峰 MyName 、小驼峰 myName、下划线 my_name
不可使用数字开头,不能使用内置关键字,严格区分大小写,以数字、字母、下划线开头。
(18)定义不变的量:字母都大写
(19)Typora 使用快捷

​ 展示路径:Ctrl+Shift+I 图片

​ 表格: |A 列名称 | B 列名称 |

(20)debug: 程序运行模式,检查程序的执行细节 。 打断点 ->debug 运行

(21)数据类型:元组 (tuple)、列表 (list)、集合 (set)、字典 (dict)

(22)格式化输出:% d 、% s、% f、%04d (不足补零,超出原样显示)、%.5f

​ \n 换行 \t 制表符 一个 Tab (4 个空格)

(23)Python 跨平台语言 :Windows、Linux、MacOS

2021.03.05

(1)Python 解释型、动态数据类型、面向对象

(2)查看系统函数帮助,按住 Ctrl,点击对应函数

(3)shift +enter 跳转到下一行

​ Ctrl + Shift + 方向键 移动代码

​ shift + tab 退一个 Tab 键

(4)float->int 强转 向下取整

(5)str(10).print ==> print(str(10))

(6)优先级:()——> ** ——> / * // %——> + -

​ 算术运算符 ——> 复合赋值运算 例:a *= 1+2 ==> a=a (1+2)——> 赋值运算符

(7)数字的逻辑运算,and 有零为零,否则返回后面的值 or 全零为零,否则返回前面的非零值

​ not 零为 False,非零为 True。

优先级:Not > and > or

(8)切片是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作。

​ 切片的语法:[起始:结束:步长]

注意:选取的区间从 "起始" 位开始,到 "结束" 位的前一位结束(不包含结束位本身),步长表示选取间隔。

2021.03.06

(1)if 条件: elif: else:

(2)字符串可以表示 bool 型数据,空格表示 False,非空格表示 True。

(3)while 先判断 后执行

2021.03.08

(1)pass 语句 补充条件语句,占位。

(2)如果使用了 continue ,则一定要在 continue 前使用计数器。

​ break 终止后退出

​ continue 跳过继续

(3)while…else… 中 else 后为正常结束后要显示的内容,非正常情况终止不会执行 else 语句

​ break 可以使程序异常退出。

​ continue 程序是正常执行的,循环结束后 else 语句会执行。

(4)” “ ”…""" 三引号支持换行

2021.03.09

(1)切片 如果步长为负数,表示倒序选取

(2)replace 修改字符串中对应的数据,原有的字符串不变。(字符串属于不可变数据类型)

​ split 分隔成列表

​ join 类似于 split 的反操作,将列表合并成字符串。

(3)capitalize 字符串首字母大写

​ title 字符串每个单词的首字母大写

​ lower 大写转小写

​ upper 小写转大写

(4)面向百度编程:Python 需求

(5) 去空白:

​ lstrip 删除左侧空格

​ rstrip 删除右侧空格

strip 删除两侧的空格

(6)对齐方式:

​ ljust (num,’_’) 在 num 长度内左对齐,多余位置用下划线补齐

​ rjust (num,’_’) 在 num 长度内右对齐,多余位置用下划线补齐

​ center (num,’_’) 在 num 长度内居中对齐,多余位置用下划线补齐

(7)字符串判断:

​ startswith () 判断字符串开头是否以某个子串开头的

​ endswith () 判断字符串是否以某个子串结尾

​ isalpha () 判断是否是字母

​ isdigit () 判断是否是数字

​ isalnum () 判断是否是数字和字母的组合

​ isspace () 判断是否都是空格

(8)列表操作:

​ append 追加整个序列到列表的结尾,修改了原列表。

​ extend 追加序列中的元素到列表的结尾

​ insert 在特定下标增加一个数据,原位置的数据后移。

​ del 删除指定数据或者列表

​ pop 删除指定下标的数据,若不指定下标,默认删除最后一个数,pop 函数会返回删除的元素。

​ remove 删除指定数据

​ clear 清空列表

​ reverse 逆置

​ sort (key =none,reverse = false) 排序 ,默认升序

​ 例如:sort (reverse = True) 降序排序

​ copy 复制列表

2021.03.10

(1)if 与 While 区别:

​ if 子句结束时,程序继续执行 if 语句之后的语句。

while 子句结束时,程序执行跳回到 while 语句开始处。

(2)在用于条件时,0、0.0 和’ '(空字符串)被认为是 False,其他值被认为是 True。

(3) for 循环

1
2
3
4
total = 0
for num in range(101):
total = total + num
print(total)

(4)实际上,只能在 while 和 for 循环内部使用 continue 和 break 语句。如果试图在别处使用这些语句,Python 将 报错。

(5)range () 函数也可以有第三个参数。前两个参数分别是起始值和终止值(不包含),第三个 参数是 “步长”。步长是每次迭代后循环变量增加的值。(类比切片作记忆)

(6)**from random import ***。 使用这种形式的 import 语句,调用 random 模块中的函数时不需要 random. 前缀。

​ 但是,使用完整的名称会让代码更可读,所以最好是使用普通形式的 import 语句。

(7)sys 模块

1
2
3
4
5
6
7
8
import sys

while True:
print('Type exit to exit:\n')
response = input()
if response == 'exit':
sys.exit()
print('You typed ' + response + '.')

(8)def 中的变量称为‘变元’,保存在变元中的值,在函数返回后就会被销毁。

(9)在 Python 中有一个值称为 None,它表示没有值。None 是 NoneType 数据类型的唯一值(其他编程语言可能称这个值为 null、nil 或 undefined)。就像布尔值 True 和 False 一样,None 必须大写首字母 N。

(10)print (sep = ‘分隔符’,end = ‘结束符’) 函数

1
2
3
4
>>> print('cats', 'dogs', 'mice')
cats dogs mice
>>> print('cats', 'dogs', 'mice', sep=',')
cats,dogs,mice

(11)可以将 “作用域” 看成是变量的容器。当作用域被销毁时,所有保存在该作用域内的变量的值就被丢弃了。

全局作用域,它是在程序开始时创建的。如果程序终止,全局作用域就被销毁,它的所有变量就被丢弃了。否则,下次你运行程序的时候,这些变量就会记住它们上次运行时的值。

​ 一个函数被调用时,就创建了一个局部作用域。在这个函数内赋值的所有变量,存在于该局部作用域内。该函数返回时,这个局部作用域就被销毁了,这些变量就丢失了。下次调用这个函数,局部变量不会记得该函数上次被调用时它们保存的值。

作用域知识点如下:

  • 全局作用域中的代码不能使用任何局部变量;
  • 但是,局部作用域可以访问全局变量;
  • 一个函数的局部作用域中的代码,不能使用其他局部作用域中的变量。
  • 如果在不同的作用域中,你可以用相同的名字命名不同的变量。也就是说,可以有一个名为 spam 的局部变量,和一个名为 spam 的全局变量。

(12)全局变量和局部变量

  • 局部作用域不能使用其他局部作用域内的变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def spam():
    eggs = 99
    bacon()
    print(eggs)
    def bacon():
    ham = 101
    eggs = 0

    spam()

    >>> 99
  • 全局变量可以在局部作用域中读取

    1
    2
    3
    4
    5
    6
    7
    8
    def spam():
    print(eggs)

    eggs = 42
    spam()
    # print(eggs)

    >>>42
  • 名称相同的局部变量和全局变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    def spam():
    eggs = 'spam local'
    print(eggs) # prints 'spam local'
    def bacon():
    eggs = 'bacon local'
    print(eggs) # prints 'bacon local'
    spam()
    print(eggs) # prints 'bacon local'

    eggs = 'global'
    bacon()
    print(eggs) # prints 'global'

    >>>
    bacon local
    spam local
    bacon local
    global

(13)global 语句

如果需要在一个函数内修改全局变量,就使用 global 语句。如果在函数的顶部有 global eggs 这样的代码,它就告诉 Python,“在这个函数中,eggs 指的是全局变量,所以不要用这个名字创建一个局部变量。”

1
2
3
4
5
6
7
8
9
def spam():
global eggs
eggs = 'spam'

eggs = 'global'
spam()
print(eggs)

>>>spam

区分一个变量是处于局部作用域还是全局作用域:

1.如果变量在全局作用域中使用(即在所有函数之外),它就总是全局变量。

2.如果在一个函数中,有针对该变量的 global 语句,它就是全局变量。

3.否则,如果该变量用于函数中的赋值语句,它就是局部变量。

4.但是,如果该变量没有用在赋值语句中,它就是全局变量。

(14)计算一个字符串中每个字符出现的次数

1
2
3
4
5
6
7
str = 'It was a bright cold day in April, and the clocks were striking thirteen.' 
count = {}
for character in str:
count.setdefault(character, 0)
count[character] += 1

print(count)

(15)漂亮的打印

1
2
3
4
5
6
7
8
import pprint
str = 'It was a bright cold day in April, and the clocks were striking
thirteen.'
count = {}
for character in str:
count.setdefault(character, 0)
count[character] += 1
pprint.pprint(count)

2021.03.11

(1)dict 大括号,键值对,逗号隔开。

(2)key : 不可变类型(int float 字符串 元组) 列表不可以

(3)del dict1 删除字典 dict1.clear 清空保留空字典

(4)在字典中 in 只能判断是否在字典中

(5)get () 查找值 keys () 查找所有的键 values () 查找所有的值

​ items () 查找字典中所有的键值对,返回元组,元组的元素分别对应 key 和 value ()

(6)set () 集合无序,可以去重,可变类型。

​ add () 增加元素到集合中,可添加不可变的容器,例如:元组、int、float、字符串

​ update () 增加数据序列,例如:列表、元组

​ remove () 删除指定数据,不存在则报错。

​ discard () 删除指定数据,不存在则不报错

​ pop () 随机删除数据,并返回删除的数据。

​ in 查找数据是否在集合内

​ not in 查找数据是否不在集合内

​ 集合可以用 for 循环遍历

(7)+ 合并 字符串、列表、元组等有序的容器都支持合并,字典不支持合并

​ * 复制 字符串、列表、元组都有序的容器支持合并,字典不支持合并

​ in 支持所有的容器

​ not in 支持所有的容器

公共方法

  • len()

  • del()

  • min()

  • max()

  • range()

  • enumerate() 返回结果是元组,元组第一个数据时对应下标,第二个元素为数据的值。

(8)列表推导式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
list1 = [i for i in range(10)]

list2 = [str(i) for i in range(10)]

# 结合if语句的列表推导式
list3 = [str(i) for i in range(10) if i % 2 == 0]

# 多个for循环实现循环嵌套的列表推导式
list4 = [(i, j) for i in range(1, 3) for j in range(3)]

# 列表推导式实现一一对应展示
l1 = ['a''b''c']
l2 = [123]
list5 = [(i, j) for i, j in zip(l1, l2)]

# 分组一个list
l1 = [i for i in range(1101)]
print(l1[::3])

# 字典推导式
list6 = [i:i**2 for i in range(15)]

# 两个列表组合的字典
list7 = ['name', 'age', 'gender']
list8 = ['Tom', 20, 'man']

dict1 = {list7[i]: list8[i] for i in range(len(list7))}
print(dict1)

# 集合推导式
list8 = [1, 1, 2]
set1 = {i ** 2 for i in list8}
print(set1) # {1, 4}

2021.03.12

(1)物品清单罗列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# inventory.py
stuff = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1, 'arrow': 12}
def displayInventory(inventory):
print("Inventory:")
item_total = 0
for k, v in inventory.items():
print(str(v) + '\t' + k)
item_total += v
print("Total number of items: " + str(item_total))
displayInventory(stuff)

>>>
Inventory:
1 rope
6 torch
42 gold coin
1 dagger
12 arrow
Total number of items: 62

(2)return 退出函数,返回值

(3)函数的说明文档:

1
2
3
4
5
6
7
8
def maxDigit(a, b):
"""最大值函数"""
if a >= b:
return a
else:
return b

help(maxDigit) # 查看函数的说明文档

(4)Ctrl + Alt +M 抽取函数

Ctrl + Q 查看函数的说明文档

(5)猜数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# This is a guess the number game. 
import random
secretNumber = random.randint(1, 20)
print('I am thinking of a number between 1 and 20.')
# Ask the player to guess 6 times.
for guessesTaken in range(1, 7):
print('Take a guess.')
guess = int(input())
if guess < secretNumber:
print('Your guess is too low.')
elif guess > secretNumber:
print('Your guess is too high.')
else:
break # This condition is the correct guess!
if guess == secretNumber:
print('Good job! You guessed my number in ' + str(guessesTaken) + ' guesses!')
else:
print('Nope. The number I was thinking of was ' + str(secretNumber))

>>>
I am thinking of a number between 1 and 20.
Take a guess.
10
Your guess is too low.
Take a guess.
15
Your guess is too low.
Take a guess.
17
Your guess is too high.
Take a guess.
16
Good job! You guessed my number in 4 guesses!

(6)函数:封装代码,高效的代码重用。

(7)变量的传递引用

变量包含对列表值的引用,而不是列表值本身

  • 在变量必须保存可变数据类型的值时,例如列表或字典,Python 就使用引用。
  • 对于不可变的数据类型的值,例如字符串、整型或元组,Python 变量就保存值本身。

(8)函数调用时,如果有位置参数,则要保证位置参数在关键字参数前面

(9)关键字列表查看

1
2
import keyword
print(keyword.kwlist)

2021.03.14

(1)Ctrl + F12 查看当前项目定义的函数的列表。
Alt + Enter 提示错误信息

(2)递归:在函数内部调用函数本身,代码量少。

1
2
3
4
5
6
7
8
9
10
11
12
# 3 + 2 + 1
def sum_numbers(num):
# 1.如果是1,直接返回1 -- 出⼝
if num == 1:
return 1
# 2.如果不是1,重复执⾏累加并返回结果
return num + sum_numbers(num - 1)


sum_result = sum_numbers(3)
# 输出结果为6
print(sum_result)

(3) lambda 表达式(匿名函数)

  • 只有一行实现
  • 可以有参数
  • 函数名代表地址,可以通过地址加括号来调用函数。
1
2
3
4
5
6
7
8
9
10
11
lambda 参数:表达式

# lambda
lambda a,b: a+b # 输入a和b,计算a+b的值。

# 带判断的lambda表达式
lambda a,b:a if a > b else b


# lambda 带key的表达式

(4)高阶函数

  • 函数有函数参数,或者函数有函数返回值。

    • sort ()

      1
      2
      3
      l = ['abcdef','ghf','treh']
      l.sort(key=lambda ele:len(ele))
      print(l) # ['ghf', 'treh', 'abcdef']
    • map(func, lst) # 将传入的函数变量 func 作用到 lst 变量的每个元素。

      1
      2
      3
      4
      5
      6
      7
      8
      my_list = [1, 2, 3, 4, 5]

      def f(x):
      return x ** 2

      result = map(f, my_list)
      # result返回内存地址,list(result)返回操作后的结果。
      print(type(result), result, list(result))
    • reduce(function, list) # 函数会对参数序列中元素进行累计

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      import functools

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


      def f(x1, x2):
      return x1 + x2


      result = functools.reduce(f, my_list)
      print(result)
    • filter(func,lst) # 过滤序列,过滤掉不符合条件的元素,返回一个 filter 对象,如果要转换为列表,可以使用 list () 来转换.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


      def f(x):
      return x % 2 == 0


      result = filter(f, my_list)
      print(list(result))

2021.03.15

(1)文件操作:

  • read() 不加参数时默认读取所有内容,加数字表示读取的字符长度。(换行符会有字节占位)
  • readlines() 将文件的内容以列表的形式展示成一行内容。参数为数字时,表示将数字以内的字符串所在行都打印出来。
  • readline() 一次读取一行内容,参数为数字时,表示读取当前行数字个字符内容,超出则读取当前行所有内容。

(2)文件指针操作

​ seek (偏移量,起始位置) 用于移动文件指针。

  • 起始位置:

    • 0: 文件开头

    • 1: 当前位置

    • 2:文件结尾

      例如:

      seek (0,2) 指针在文件的结尾

      seek (n,0) 指针在文件的开头,从 n+1 个字符读文件。

      seek (0,0) 等价于 seek (0),指针放在文件开头。

      seek (-2,2) 以结尾为基准,偏移两个字节,即读取后两个字符。

(3)相对路径

  • ./ 根目录
  • …/ 上一级目录
  • …/…/ 上上一级目录

(4)文件的相关操作:

  • 文件重命名

    os 模块中的 rename () 可以完成对文件的重命名操作

    rename (需要修改的文件名,新的文件名)

    1
    2
    import os
    os.rename("毕业论文.txt", "毕业论文-最终版.txt")
  • 删除文件

    os 模块中的 remove () 可以完成对文件的删除操作

    remove (待删除的文件名)

    1
    2
    import os
    os.remove("毕业论文.txt")
  • 创建文件夹

    1
    2
    import os
    os.mkdir("张三")
  • 获取当前目录

    1
    2
    import os
    os.getcwd()
  • 改变默认目录

    1
    2
    import os
    os.chdir("../")
  • 获取目录列表

    1
    2
    import os
    os.listdir("./")
  • 删除文件夹

    1
    2
    import os
    os.rmdir("张三")

2021.03.19

(1)面向对象:强调对象(实体),我们充当指挥者的角色

 面向过程:强调过程(动作),我们充当**执行者**的角色

(2)面向对象的特征:继承、封装、多态。

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制

通过继承创建的新类称为子类派生类,被继承的类称为基类父类超类

(3)用类去创建对象 ==> 用类去实例化对象

(4)类是对一系列具有相同特征(属性)和行为(方法)的事物的统称,遵循大驼峰命名规则。

​ 对象是具体的类

(5)self : 调用该函数的对象,不需要传递。也可以用其它字符代替。

​ 类里面获取属性:self. 属性名

(6)魔法方法:类里面都具备的方法,以‘–’开头结尾的都是魔法方法,创建对象的时候自动执行。

  • 成员属性:作用域:通过对象访问
  • 局部变量:作用域:在函数内部使用

(7) 魔法方法

1
2
3
4
5
6
7
8
9
# __init__  初始化对象,可以传递参数。

# __str__ 代替对象的内存地址为reture的返回值,当使用print输出对象的时候,直接打印这个返回值,作为对这个对象的描写。

# __del__ 删除对象时,会调用该方法 (析构函数)

# __repr__ 转化为供解释器读取的形式

# __cmp__ ( self, x ) 对象比较

运算符重载

Python 同样支持运算符重载,实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b

def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)

def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2

>>>Vector(7,8)

Python 内置类属性

  • dict : 类的属性(包含一个字典,由类的数据属性组成)

  • doc : 类的文档字符串

  • name: 类名

  • module: 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块 mymod 中,那么 className.module 等于 mymod)

  • bases : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    class Employee:
    '所有员工的基类'
    empCount = 0

    def __init__(self, name, salary):
    self.name = name
    self.salary = salary
    Employee.empCount += 1

    def displayCount(self):
    print "Total Employee %d" % Employee.empCount

    def displayEmployee(self):
    print "Name : ", self.name, ", Salary: ", self.salary

    print "Employee.__doc__:", Employee.__doc__
    print "Employee.__name__:", Employee.__name__
    print "Employee.__module__:", Employee.__module__
    print "Employee.__bases__:", Employee.__bases__
    print "Employee.__dict__:", Employee.__dict__



    >>>Employee.__doc__: 所有员工的基类
    Employee.__name__: Employee
    Employee.__module__: __main__
    Employee.__bases__: ()
    Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}

Python 对象销毁 (垃圾回收)

  • Python 使用了引用计数这一简单技术来跟踪和回收垃圾。

在 Python 内部记录着所有使用中的对象各有多少引用。

  • 一个内部跟踪变量,称为一个引用计数器。

  • 当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为 0 时, 它被垃圾回收。但是回收不是 "立即" 的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。

  • 垃圾回收机制不仅针对引用计数为 0 的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。

  • Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充,垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。

2021.03.20

(1)多继承

  • 继承多个父类,优先继承第一个父类

  • 子类可以调用所有父类中不同名的方法

  • 如果子类和父类拥有同名属性和方法,则子类创建出来的对象会直接调用子类自己的属性和方法,即子类重写父类方法

  • 子类调用父类的同名方法和属性:

    • 先调用自己子类方法的初始化

      1
      2
      3
      4
      def make_cakeself):
      # 添加自己的初始化
      self.__init__() # 不需要加self
      print('子类打印内容')
    • 将父类同名属性和方法再次封装

      1
      2
      3
      4
      5
      def make_master_cake(self,name):
      # 首先调用init初始化属性
      Master.__init__(self,name)
      # 调用父类同名的方法和属性
      Master.make_cake(self)

(2)print (类名.__mro__) # 显示该类的继承关系

(3)多层继承:

  • super () 调用父类,适用单继承

  • 如果重写了__init__ 时,要继承父类的构造方法,可以使用 super 关键字:

    1
    super(子类,self).__init__(参数1,参数2,....)

    还有一种经典写法:

    1
    父类名称.__init__(self,参数1,参数2,...)

(4)定义私有属性和方法(私有属性和方法不能被子类继承)

类的私有属性

__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

类的方法

在类的内部,使用 def 关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数

类的私有方法

__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用 self.__private_methods

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量

def count(self):
self.__secretCount += 1
self.publicCount += 1
print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print(counter.publicCount)
print(counter.__secretCount) # 报错,实例不能访问私有变量


>>>
1
2
2
Traceback (most recent call last):
File "test.py", line 17, in <module>
print counter.__secretCount # 报错,实例不能访问私有变量
AttributeError: JustCounter instance has no attribute '__secretCount'
  • 只能在类内使用,外部打印是不能的。

  • Python 不允许实例化的类访问私有数据,但你可以使用 object._className__attrName( 对象名._类名__私有属性名 )访问属性

    1
    2
    3
    4
    5
    6
    7
    8
    class Runoob:
    __site = "www.runoob.com"

    runoob = Runoob()
    print(runoob._Runoob__site)

    >>>
    www.runoob.com

(5) 获取和修改私有属性值

  • get_XX

    在类里面定义函数调用私有属性,外部调用该方法显示私有属性值。

  • set_XX
    在类里面定义函数调用私有属性,外部调用该方法设置私有属性值。

(6)多态(同一功能,不同表现形式 —— 静态类型语言)

(7)封装

  • 隐藏内部实现的细节,只保留功能接口。
  • 前提是私有化
  • 函数、类、模块、包等都是封装

shift +F6 Pycharm 中替换功能

(8)单下划线、双下划线、头尾双下划线说明:

  • __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似 init () 之类的。
  • _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
  • __foo: 双下划线的表示的是私有类型 (private) 的变量,只能是允许这个类本身进行访问了。

(9)继承 object 类的是新式类,不继承 object 类的是经典类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A:
def foo(self):
print('called A.foo()')

class B(A):
pass

class C(A):
def foo(self):
print('called C.foo()')

class D(B, C):
pass

if __name__ == '__main__':
d = D()
d.foo()
  • B、C 是 A 的子类,D 多继承了 B、C 两个类,其中 C 重写了 A 中的 foo () 方法。
  • 如果 A 是经典类(如上代码),当调用 D 的实例的 foo () 方法时,Python 会按照深度优先的方法去搜索 foo () ,路径是 B-A-C ,执行的是 A 中的 foo () ;
  • 如果 A 是新式类,当调用 D 的实例的 foo () 方法时,Python 会按照广度优先的方法去搜索 foo () ,路径是 B-C-A ,执行的是 C 中的 foo () 。
  • 因为 D 是直接继承 C 的,从逻辑上说,执行 C 中的 foo () 更加合理,因此新式类对多继承的处理更为合乎逻辑。
  • 在 Python 3.x 中的新式类貌似已经兼容了经典类,无论 A 是否继承 object 类, D 实例中的 foo () 都会执行 C 中的 foo () 。
  • 但是在 Python 2.7 中这种差异仍然存在,因此还是推荐使用新式类,要继承 object 类。

(10)所有的实例都共享类属性,因此,当在 class 语句外修改类属性时,会导致所有由这个类创建的实例的类属性都随之变化,除非实例本身有同名的实例属性对类属性进行了覆盖,比如代码中的 d.cls_pre = ‘ddddd’。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class CA(object):

cls_pre = 'aaaaa'

def __init__(self):
self.obj_pre = 'bbbbb'

a = CA()
b = CA()

print(a.cls_pre, a.obj_pre)
print(b.cls_pre, b.obj_pre)

CA.cls_pre = 'ccccc'
c = CA()

d = CA()
d.cls_pre = 'ddddd'

print(a.cls_pre, a.obj_pre)
print(b.cls_pre, b.obj_pre)
print(c.cls_pre, c.obj_pre)
print(d.cls_pre, d.obj_pre)


>>>
aaaaa bbbbb
aaaaa bbbbb
ccccc bbbbb
ccccc bbbbb
ccccc bbbbb
ddddd bbbbb

代码中,将类属性 CA.cls_pre 重新赋值为 ‘ccccc’。在修改类属性之后,不仅是后续创建的类实例 c 的 cls_pre 发生变化,在修改类属性之前的创建的类实例 a、b 的类属性 cls_pre 都发生了变化。

2021.03.21

Python 内置函数:

  • abs()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    print(abs(-45))
    print(abs(100.12))
    print(abs(119L))
    print(abs(1+2j)) # 如果为复数时,则返回复数的绝对值,即a^2 + b^2 开根。


    >>>
    45
    100.12
    119
    2.23606797749979
  • divmod () 返回一个包含商和余数的元组 (a //b, a % b)

1
2
3
4
5
6
>>>divmod(7, 2)
(3, 1)
>>> divmod(8, 2)
(4, 0)
>>> divmod(1+2j,1+0.5j)
((1+0j), 1.5j)
  • staticmethod 返回函数的静态方法,该方法不强制要求传递参数,即静态方法无需实例化,减少不必要的内存占用和性能消耗
1
2
3
4
5
6
7
8
9
10
11
12
13
class C(object):
@staticmethod
def f():
print('runoob');

C.f(); # 静态方法无需实例化
cobj = C()
cobj.f() # 也可以实例化后调用


>>>
runoob
runoob

staticmethod 参数要求是 Callable, 也就是说 Class 也是可以的:

1
2
3
4
5
6
7
8
9
10
class C1(object):
@staticmethod
class C2(object):
def __init__(self, val = 1):
self.val = val
def shout(self):
print("Python世界第%d!"%self.val)
tmp = C1.C2(0)
print(type(tmp)) # 输出 : <class '__main__.C1.C2'>
tmp.shout() # 输出 : Python世界第0!
  • all () 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。元素除了是 0、空、None、False 外都算 True。
    • 注意:空元组、空列表返回值为 True,这里要特别注意。
    • 所以的为真则为 Ture
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> all(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True
>>> all(['a', 'b', '', 'd']) # 列表list,存在一个为空的元素
False
>>> all([0, 12, 3]) # 列表list,存在一个为0的元素
False

>>> all(('a', 'b', 'c', 'd')) # 元组tuple,元素都不为空或0
True
>>> all(('a', 'b', '', 'd')) # 元组tuple,存在一个为空的元素
False
>>> all((0, 1, 2, 3)) # 元组tuple,存在一个为0的元素
False

>>> all([]) # 空列表
True
>>> all(()) # 空元组
True
  • any () 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。
    • 如果都为空、0、false,则返回 false,如果不都为空、0、false,则返回 true。
    • 注意:空元组、空列表返回值为 False,这里要特别注意。
    • 任何一个有效则为 True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
>>>any(['a', 'b', 'c', 'd'])  # 列表list,元素都不为空或0
True

>>> any(['a', 'b', '', 'd']) # 列表list,存在一个为空的元素
True

>>> any([0, '', False]) # 列表list,元素全为0,'',false
False

>>> any(('a', 'b', 'c', 'd')) # 元组tuple,元素都不为空或0
True

>>> any(('a', 'b', '', 'd')) # 元组tuple,存在一个为空的元素
True

>>> any((0, '', False)) # 元组tuple,元素全为0,'',false
False

>>> any([]) # 空列表
False

>>> any(()) # 空元组
False

  • enumerate () 函数用于将一个可遍历的数据对象 (如列表、元组或字符串) 组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1)) # 下标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

# 普通for循环

>>>i = 0
>>> seq = ['one', 'two', 'three']
>>> for element in seq:
... print i, seq[i]
... i +=1
...
0 one
1 two
2 three


# For循环使用enumerate

>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
... print i, element
...
0 one
1 two
2 three
1
2
3
4
5
6
7
8
9
10
11
12
# 巧妙的利用enumerate()批量修改列表中的元素
list1 = ['01','02','03']
unit_element = '1'

# list1=["1"+str for str in list1] #推导式实现拼接

for i,element in enumerate(list1):
list1[i] = unit_element + element # 字符串拼接
print(list1)

>>>
['101', '102', '103']
  • ord© 返回值是对应的 ASCII 码(十进制整数)。
1
2
3
4
5
6
>>>ord('a')
97
>>> ord('b')
98
>>> ord('c')
99
  • isinstance () 函数来判断一个对象是否是一个已知的类型,类似 type ()。

    • isinstance () 与 type () 区别:

      • type () 不会认为子类是一种父类类型,不考虑继承关系。
      • isinstance () 会认为子类是一种父类类型,考虑继承关系。

      如果要判断两个类型是否相同推荐使用 isinstance ()。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>>a = 2
>>> isinstance (a,int)
True
>>> isinstance (a,str)
False
>>> isinstance (a,(str,int,list)) # 是元组中的一个返回 True
True



# type()和isinstance()的区别
class A:
pass

class B(A):
pass

isinstance(A(), A) # returns True
type(A()) == A # returns True
isinstance(B(), A) # returns True
type(B()) == A # returns False

  • pow() 方法返回 xy(x 的 y 次方) 的值。
    • pow (x, y [, z]) 等效于 pow (x,y) % z,当 z 这个参数不存在时 x,y 不限制是否为 float 类型,而当使用第三个参数的时候要保证前两个参数只能为整数
    • pow (x, y) 并不等价与 x**y,因为 pow 函数会把整数转换为浮点数,会出现误差。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import math   # 导入 math 模块

print f'math.pow(100, 2):{math.pow(100, 2)}'
# 使用内置,查看输出结果区别
print f'pow(100, 2):{pow(100, 2)}'

print f'math.pow(100, -2) : {math.pow(100, -2)}'
print f'math.pow(2, 4) :{math.pow(2, 4)}'
print f'math.pow(3, 0) : {math.pow(3, 0)}'

#pow(x, y[, z]) 等效于 pow(x,y) %z
print(4**2.5%3) # 结果为2.0

>>>
math.pow(100, 2) : 10000.0
pow(100, 2) : 10000
math.pow(100, -2) : 0.0001
math.pow(2, 4) : 16.0
math.pow(3, 0) : 1.0
2.0
  • sum() 方法对序列进行求和计算。
    • iterable – 可迭代对象,如:列表、元组、集合。
    • start – 指定相加的参数,如果没有设置这个值,默认为 0。
1
2
3
4
5
6
7
>>>sum([0,1,2])  
3
>>> sum((2, 3, 4), 1) # 元组计算总和后再加 1
10
>>> sum([0,1,2,3,4], 2) # 列表计算总和后再加 2
12

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np

a = np.array([[1,2],[3,4]])

# 按行相加,并且保持其二维特性
print(np.sum(a, axis=1, keepdims=True))

# 按行相加,不保持其二维特性
print(np.sum(a, axis=1))

>>>
array([[3], [7]])
array([3, 7])
  • issubclass (class, classinfo) 用于判断参数 class 是否是类型参数 classinfo 的子类。
1
2
3
4
5
6
class A:
pass
class B(A):
pass

print(issubclass(B,A)) # 返回 True
  • bin() 返回一个整数 int 或者长整数 long int 的二进制表示。
1
2
3
4
5
>>>bin(10)
'0b1010'
>>> bin(20)
'0b10100'

  • range (start, stop [, step]) 函数可创建一个整数列表,一般用在 for 循环中。

    参数说明:

    • start: 计数从 start 开始。默认是从 0 开始。例如 range(5)等价于 range(0, 5);
    • stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是 [0, 1, 2, 3, 4] 没有 5
    • step:步长,默认为 1。例如:range(0, 5) 等价于 range (0, 5, 1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>>range(10)        # 从 0 开始到 10
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11) # 从 1 开始到 11
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5) # 步长为 5
[0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3) # 步长为 3
[0, 3, 6, 9]
>>> range(0, -10, -1) # 负数
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0)
[]
>>> range(1, 0)
[]

range () 函数返回的结果是一个整数序列的对象,而不是列表。

1
2
3
4
5
6
7
8
9
>>> type(range(10))
<class 'range'>

>>>help(range)
Return an object...

# 将range()函数返回一个列表
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1
2
3
4
5
6
7
8
9
10
11
12
13
print([i for i in range(10)])
# 用来做计算
print([x*x for x in range(2, 8)])

# 两层循环,生成全排列的list
print(type([m + n for m in 'ABC' for n in 'XYZ']))
print([m + n for m in 'ABC' for n in 'XYZ'])

# 这种方式生成单个str
for m in 'ABC':
for n in 'XYZ':
print(type(m + n))
print(m + n)

range 生成的列表,列表中的元素相互独立,即地址各不相同,这与 * 号重复列表生成的列表大相径庭,前者类似深拷贝,后者则纯粹是浅拷贝,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a = [0] * 3
print u'这是浅拷贝'
for num in a:
print id(num)
b = range(3)
print u'这是深拷贝'
for num in b:
print id(num)


>>>
这是浅拷贝
54813568
54813568
54813568
这是深拷贝
54813568
54813544
54813520
  • callable() 函数用于检查一个对象是否是可调用的。

    • 如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。

    • 对于函数、方法、lambda 函式、 类以及实现了 __call__ 方法的类实例,它都返回 True。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
>>>callable(0)
False
>>> callable("runoob")
False

>>> def add(a, b):
... return a + b
...
>>> callable(add) # 函数返回 True
True
>>> class A: # 类
... def method(self):
... return 0
...
>>> callable(A) # 类返回 True
True
>>> a = A()
>>> callable(a) # 没有实现 __call__, 返回 False
False
>>> class B:
... def __call__(self):
... return 0
...
>>> callable(B)
True
>>> b = B()
>>> callable(b) # 实现 __call__, 返回 True
True
  • locals() 函数会以字典类型返回当前位置的全部局部变量。

    对于函数,方法,lambda 函式,类,以及实现了 __call__ 方法的类实例,它都返回 True。

1
2
3
4
5
6
>>>def runoob(arg):    # 两个局部变量:arg、z
... z = 1
... print (locals())
...
>>> runoob(4)
{'z': 1, 'arg': 4} # 返回一个名字/值对的字典
  • reduce() 函数会对参数序列中元素进行累积。

    函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from functools import reduce

def add(x, y) : # 两数相加
return x + y
sum1 = reduce(add, [1,2,3,4,5]) # 调用add函数,计算列表和:1+2+3+4+5

sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
print(sum1)
print(sum2)


>>>
15
15
1
2
3
4
5
6
7
8
9
from functools import reduce

def add(x,y):
return x + y

print (reduce(add, range(1, 101)))

>>>
5050
1
2
3
4
5
6
7
8
# 统计某字符串重复次数:
from functools import reduce
sentences = ['The Deep Learning textbook is a resource intended to help students and practitioners enter the field of machine learning in general and deep learning in particular. ']
word_count =reduce(lambda a,x:a+x.count("learning"),sentences,0)
print(word_count)

>>>
2
1
2
3
4
5
6
7
# 实现字符串反转

from functools import reduce

str1="hello"
print(reduce(lambda x,y:y+x,str1))
# 输出 olleh
  • chr () 用一个范围在 range(256)内的(就是 0~255)整数作参数,返回一个对应的字符。
1
2
3
4
>>>print chr(0x30), chr(0x31), chr(0x61)   # 十六进制
0 1 a
>>> print chr(48), chr(49), chr(97) # 十进制
0 1 a
  • classmethod()装饰器 访问私有类或者类属性使用,cls 指代当前类
1
2
3
4
5
6
7
8
9
10
11
12
13
class A(object):
bar = 1

def func1(self): # self 指代对象
print ('foo')

@classmethod
def func2(cls):
print ('func2')
print (cls.bar) # 调用类属性
cls().func1() # 调用类中方法

A.func2() # 不需要实例化
  • staticmethod() 。+
1

2021.03.22

(1)异常

  • 检查时异常

  • 运行时异常

    解决异常的方法

    • 捕捉异常可以使用 try/except 语句。

      try/except 语句用来检测 try 语句块中的错误,从而让 except 语句捕获异常信息并处理。

      如果你不想在异常发生时结束你的程序,只需在 try 里捕获它。

    1
    2
    3
    4
    5
    6
    7
    8
    try:
    <语句> #运行别的代码
    except <名字>:
    <语句> #如果在try部份引发了'name'异常
    except <名字>,<数据>:
    <语句> #如果引发了'name'异常,获得附加的数据
    else:
    <语句> #如果没有异常发生
    • try 的工作原理:当开始一个 try 语句后,python 就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try 子句先执行,接下来会发生什么依赖于执行时是否出现异常。

      • 如果当 try 后的语句执行时发生异常,python 就跳回到 try 并执行第一个匹配该异常的 except 子句,异常处理完毕,控制流就通过整个 try 语句(除非在处理异常时又引发新的异常)。
      • 如果在 try 后的语句里发生了异常,却没有匹配的 except 子句,异常将被递交到上层的 try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
      • 如果在 try 子句执行时没有发生异常,python 将执行 else 语句后的语句(如果有 else 的话),然后控制流通过整个 try 语句
    • 异常名称 描述
      BaseException 所有异常的基类
      SystemExit 解释器请求退出
      KeyboardInterrupt 用户中断执行 (通常是输入 ^C)
      Exception 常规错误的基类
      StopIteration 迭代器没有更多的值
      GeneratorExit 生成器 (generator) 发生异常来通知退出
      StandardError 所有的内建标准异常的基类
      ArithmeticError 所有数值计算错误的基类
      FloatingPointError 浮点计算错误
      OverflowError 数值运算超出最大限制
      ZeroDivisionError 除 (或取模) 零 (所有数据类型)
      AssertionError 断言语句失败
      AttributeError 对象没有这个属性
      EOFError 没有内建输入,到达 EOF 标记
      EnvironmentError 操作系统错误的基类
      IOError 输入 / 输出操作失败
      OSError 操作系统错误
      WindowsError 系统调用失败
      ImportError 导入模块 / 对象失败
      LookupError 无效数据查询的基类
      IndexError 序列中没有此索引 (index)
      KeyError 映射中没有这个键
      MemoryError 内存溢出错误 (对于 Python 解释器不是致命的)
      NameError 未声明 / 初始化对象 (没有属性)
      UnboundLocalError 访问未初始化的本地变量
      ReferenceError 弱引用 (Weak reference) 试图访问已经垃圾回收了的对象
      RuntimeError 一般的运行时错误
      NotImplementedError 尚未实现的方法
      SyntaxError Python 语法错误
      IndentationError 缩进错误
      TabError Tab 和空格混用
      SystemError 一般的解释器系统错误
      TypeError 对类型无效的操作
      ValueError 传入无效的参数
      UnicodeError Unicode 相关的错误
      UnicodeDecodeError Unicode 解码时的错误
      UnicodeEncodeError Unicode 编码时错误
      UnicodeTranslateError Unicode 转换时错误
      Warning 警告的基类
      DeprecationWarning 关于被弃用的特征的警告
      FutureWarning 关于构造将来语义会有改变的警告
      OverflowWarning 旧的关于自动提升为长整型 (long) 的警告
      PendingDeprecationWarning 关于特性将会被废弃的警告
      RuntimeWarning 可疑的运行时行为 (runtime behavior) 的警告
      SyntaxWarning 可疑的语法的警告
      UserWarning 用户代码生成的警告

    使用 except 而带多种异常类型

    1
    2
    3
    4
    5
    6
    7
    8
    try:
    正常的操作
    ......................
    except(Exception1[, Exception2[,...ExceptionN]]]):
    发生以上多个异常中的一个,执行这块代码
    ......................
    else:
    如果没有异常执行这块代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # finally 触发异常
    """
    当在try块中抛出一个异常,立即执行finally块代码。
    finally块中的所有语句执行后,异常被再次触发,并执行except块代码。
    """
    try:
    fh = open("testfile", "w")
    try:
    fh.write("这是一个测试文件,用于测试异常!!")
    finally:
    print "关闭文件"
    fh.close()
    except IOError:
    print "Error: 没有找到文件或读取文件失败"
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     # 触发异常后,后面的代码就不会再执行
    # 定义函数
    def mye( level ):
    if level < 1:
    raise Exception,"Invalid level!"
    # 触发异常后,后面的代码就不会再执行
    try:
    mye(0) # 触发异常
    except Exception,err:
    print 1,err
    else:
    print 2


    >>>
    $ python test.py
    1 Invalid level!

    (2)Python 模块 (Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和 Python 语句。

    • 模块让你能够有逻辑地组织你的 Python 代码段。
    • 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
    • 模块能定义函数,类和变量,模块里也能包含可执行的代码。

dir () 函数

返回一个排好序的字符串列表,内容是一个模块里定义过的名字。

返回的列表容纳了在一个模块里定义的所有模块,变量和函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 导入内置math模块
import math

content = dir(math)

print content;


>>>
['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan',
'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp',
'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh',
'sqrt', 'tan', 'tanh']

在这里,特殊字符串变量__name__指向模块的名字,__file__指向该模块的导入文件名。

globals () 和 locals () 函数

根据调用地方的不同,globals () 和 locals () 函数可被用来返回全局和局部命名空间里的名字。

  • 如果在函数内部调用 locals(),返回的是所有能在该函数里访问的局部命名。

  • 如果在函数内部调用 globals(),返回的是所有在该函数里能访问的全局名字。

两个函数的返回类型都是字典。所以名字们能用 keys() 函数摘取。

2021.03.23

(1)模块导入 **__name__**

在模块中运行:__main__

在模块外运行:模块名称

2021.03.25

(1)操作系统:向下控制硬件,向上控制软件。

(2)操作命令快捷指令

  • ctrl + L 显示文件的绝对路径

  • Ctrl+Alt+T 打开终端

  • Ctrl+Shift+C 命令行复制

  • Ctrl+Shift+V 命令行粘贴

  • Ctrl +Shift +’+’ 放大终端的字体

  • Ctrl+’-’ 缩小终端的字体

  • arch 机器的处理器架构

  • uname -r 内核版本、

  • cat /proc/cpuinfo 处理器信息

  • cat /proc/version 发行版本信息

  • ls 查看当前路径下的目录信息

  • ls python* 查找所有以 python 开头的文件

  • cd 进入路径目录

  • pwd 显示当前路径

  • tree 按树结构显示路径下的目录信息

  • clear => ctrl + L

  • sudo apt install terminator 第三方终端

  • cd - 回到上一次目录

  • cd … 切换到上层目录

  • cd . 切换 到当前目录

  • cd ~ 切换到当前用户的主目录

  • cd …/… 切换到上两层的目录

  • touch 创建文件 (夹)

  • mkdir 创建文件夹

  • mkdir -p aa/bb/cc 创建多级目录

  • rm 删除文件

  • rmdir 文件夹名 删除空文件夹

  • rm -r 文件夹名 递归删除文件夹

  • rm -f 强制删除

  • rm -i 交互式提示

  • rm -rf 递归强制删除文件或文件夹

  • cp

  • cp -r 递归拷贝文件 (recursive)

  • mv 剪切文件 / 文件夹。重命名

  • ls -lh 智能显示文件列表

  • ls -al => ll

  • mv -v 显示文件的操作信息

  • > 重定向到其它文件

  • >> 重定向追加到文件

  • cat a.txt b.txt > c.txt

  • more 命令 f 前 b 后 q 退出

  • | 管道

  • ln -s 软链接,创建快捷方式

  • ln 硬链接,备份数据

2021.03.28

(1) 多任务:

  • 并发:任务数 > CPU 核心数,CPU 交替执行
  • 并行:任务数 <=CPU 核心数,每个 CPU 都可以执行一个任务

(2) 进程是资源分配的最小单位,一个运行程序就是用一个进程.

  • 默认启动的是主进程,后续启动的为子进程

  • 进程创建的步骤:

    • import multiprocessing
    • 进程对象 = multiprocessing.Process (target= 函数名)
    • 进程对象.start ()
  • 获取进程的方法

    • os.getpid () 获取当前进程 ID
    • os.getppid () 获取父进程 ID
  • 函数本身无进程之分,被调用时会区分

    • 如果直接调用,则为主进程。
    • 若被进程调用,则为子进程。
  • IPC inter process communication 进程间共享全局变量使用

  • 进程守护

    • 进程对象 = multiprocessing.Process (target= 函数名)
    • # 进程对象.daemon = True # (被动)守护主进程方法一
    • 进程对象.start ()
    • # 进程对象.terminate () # (主动)守护主进程方法二
  • 进程对象.join () 把并行执行 变成 串行执行,用于在一个进程执行后去执行另一个进程的场景

  • ps

    • -a 所有进程

    • -x 无控制台终端

    • -u

      ps -aux|grep pycharm

      ps -aux --sort -pcpu | less 根据 CPU 使用来升序排序

      ps -aux --sort -pmem | less 根据 内存使用 来升序排序

      ps -aux --sort -pcpu,+pmem | head -n 10 将 CPU 使用和内存使用合并到一个命令,并通过管道显示前 10 个结果。

      ps -axjf 树形显示进程

      ps -f -C getty 使用 - f 参数来查看格式化的一个名为 getty 的进程的信息

  • kill -9 进程编号

  • 线程

    • 程序执行的最小单位

    • 实现多任务的一种方式

    • 进程默认会有一个线程

    • 进程是分配资源,线程是执行单元

    • 同一个进程中,多个线程共享资源

      • import threading

      • 线程对象 = threading.Thread (target = 函数名, daemon = True) # 方法一 : 守护主进程

      • # 线程对象.setDaemon(True) 方法二: 守护主线程

      • 线程对象.start ()

    • 线程执行是无序的

    • 获取线程名称: threading.current_thread ().name

    • 线程同步:为解决多线程之间共享全局变量数据出现资源竞争,导致出现错误的情况(修改全局变量的操作是非原子性的)

      • 互斥锁

        • 创建互斥锁 mutex = threading.Lock ()

        • 上锁 mutex.acquire ()

        • 解锁 mutex.release ()

  • join 和互斥锁的异同:

    • 同:都是将并发变成串行
    • 异:
      • join 是将一个任务整体串行
      • 互斥锁可以将一个任务中的某一段代码串行

2021.04.03

  • property 属性

    • 定义 property 属性有两种方式:
      1. 装饰器方式
      2. 类属性方式
    • 装饰器方式:
      1. @property 修饰获取值的方法
      2. @方法名.setter 修饰设置值的方法
    • 类属性方式:
      1. 类属性 = property (获取值方法,设置值方法)
  • with 语句

    • 执行完成以后自动调用关闭文件操作,即使出现异常也会自动调用关闭文件操作。
  • 上下文管理器

    • 一个类只要实现了 __enter__()和__exit__() 这个两个方法,通过该类创建的对象我们就称之为上下文管理器。

    • with 语句之所以这么强大,背后是由上下文管理器做支撑的

    • 使用 open 函数创建的文件对象就是一个上下文管理器对象。

    • __enter__ 表示上文方法,需要返回一个操作文件对象

    • __exit__ 表示下文方法,with 语句执行完成会自动执行,即使出现异常也会执行该方法。

    • Python 提供了 with 语句用于简化资源释放的操作,使用 with 语句操作建立在上下文管理器 (实现 __enter__和__exit__ ) 的基础上

  • 生成器

    • 根据程序员制定的规则循环生成数据,当条件不成立时则生成数据结束。数据不是一次性全部生成出来,而是使用一个,再生成一个,可以节约大量的内存
    • next 函数获取生成器中的下一个值
    • for 循环遍历生成器中的每一个值
  • yield 关键字

    • 只要在 def 函数里看到 yield 关键字就是生成器
    • 生成器是根据算法生成数据的一种机制,每次调用生成器只生成一个值,可以节省大量内存。
    • 生成器的创建有两种方式:
      • 生成器推导式
      • yield 关键字
  • 深拷贝和浅拷贝

    • 浅拷贝:

      • 不可变类型的浅拷贝说明:

        • 通过上面的执行结果可以得知,不可变类型进行浅拷贝不会给拷贝的对象开辟新的内存空间,而只是拷贝了这个对象的引用。
      • 可变类型的浅拷贝说明:

        • 通过上面的执行结果可以得知,可变类型进行浅拷贝只对可变类型的第一层对象进行拷贝,对拷贝的对象会开辟新的内存空间进行存储,子对象不进行拷贝。

          浅拷贝存在的问题:

          虽然浅拷贝可以解决最开始直接赋值存在的问题,但如果数据内部有子元素为可变类型还会有问题

  • 深拷贝:

    • 不可变类型的深拷贝说明:

      • 不可变类型进行深拷贝如果子对象没有可变类型则不会进行拷贝,而只是拷贝了这个对象的引用,否则会对该对象到最后一个可变类型的每一层对象就行拷贝,对每一层拷贝的对象都会开辟新的内存空间进行存储
    • 可变类型的深拷贝说明:

      • 可变类型进行深拷贝会对该对象到最后一个可变类型的每一层对象就行拷贝,对每一层拷贝的对象都会开辟新的内存空间进行存储。
  • 浅拷贝和深拷贝的区别

    • 浅拷贝最多拷贝对象的一层
    • 深拷贝可能拷贝对象的多层
  • 正则表达式

    • 在实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等,这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。

    • 正则表达式就是记录文本规则的代码

    • # 导入 re 模块
      import re
      # 使用 match 方法进行匹配操作
      result = re.match(正则表达式,要匹配的字符串)
      # 如果上一步匹配到数据的话,可以使用 group 方法来提取数据
      result.group()
      <!--code71-->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import re

# 如果hello的首字符小写,那么正则表达式需要小写的h
ret = re.match("h","hello Python")
print(ret.group())


# 如果hello的首字符大写,那么正则表达式需要大写的H
ret = re.match("H","Hello Python")
print(ret.group())

# 大小写h都可以的情况
ret = re.match("[hH]","hello Python")
print(ret.group())
ret = re.match("[hH]","Hello Python")
print(ret.group())
ret = re.match("[hH]ello Python","Hello Python")
print(ret.group())

# 匹配0到9第一种写法
ret = re.match("[0123456789]Hello Python","7Hello Python")
print(ret.group())

# 匹配0到9第二种写法
ret = re.match("[0-9]Hello Python","7Hello Python")
print(ret.group())

ret = re.match("[0-35-9]Hello Python","7Hello Python")
print(ret.group())

# 下面这个正则不能够匹配到数字4,因此ret为None
ret = re.match("[0-35-9]Hello Python","4Hello Python")
# print(ret.group())

>>>
h
H
h
H
Hello Python
7Hello Python
7Hello Python
7Hello Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import re

# 普通的匹配方式
ret = re.match("嫦娥1号","嫦娥1号发射成功")
print(ret.group())

ret = re.match("嫦娥2号","嫦娥2号发射成功")
print(ret.group())

ret = re.match("嫦娥3号","嫦娥3号发射成功")
print(ret.group())

# 使用\d进行匹配
ret = re.match("嫦娥\d号","嫦娥1号发射成功")
print(ret.group())

ret = re.match("嫦娥\d号","嫦娥2号发射成功")
print(ret.group())

ret = re.match("嫦娥\d号","嫦娥3号发射成功")
print(ret.group())


>>>
嫦娥1
嫦娥2
嫦娥3
嫦娥1
嫦娥2
嫦娥3
1
2
3
4
5
6
7
8
9
10
11
12
import re

match_obj = re.match("\D", "f")
if match_obj:
# 获取匹配结果
print(match_obj.group())
else:
print("匹配失败")


>>>
f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import re

# 空格属于空白字符
match_obj = re.match("hello\sworld", "hello world")
if match_obj:
result = match_obj.group()
print(result)
else:
print("匹配失败")



# \t 属于空白字符
match_obj = re.match("hello\sworld", "hello\tworld")
if match_obj:
result = match_obj.group()
print(result)
else:
print("匹配失败")


>>>
hello world
hello world
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import re

match_obj = re.match("hello\Sworld", "hello&world")
if match_obj:
result = match_obj.group()
print(result)
else:
print("匹配失败")



match_obj = re.match("hello\Sworld", "hello$world")
if match_obj:
result = match_obj.group()
print(result)
else:
print("匹配失败")

>>>
hello&world
hello$world
1
2
3
4
5
6
7
8
9
10
11
12
import re

# 匹配非特殊字符中的一位
match_obj = re.match("\w", "A")
if match_obj:
# 获取匹配结果
print(match_obj.group())
else:
print("匹配失败")

>>>
A
1
2
3
4
5
6
7
8
9
10
# 匹配特殊字符中的一位
match_obj = re.match("\W", "&")
if match_obj:
# 获取匹配结果
print(match_obj.group())
else:
print("匹配失败")

>>>
&
代码 功能
* 匹配前一个字符出现 0 次或者无限次,即可有可无
+ 匹配前一个字符出现 1 次或者无限次,即至少有 1 次
? 匹配前一个字符出现 1 次或者 0 次,即要么有 1 次,要么没有
匹配前一个字符出现 m 次
匹配前一个字符出现从 m 到 n 次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re

ret = re.match("[A-Z][a-z]*","M")
print(ret.group())

ret = re.match("[A-Z][a-z]*","MnnM")
print(ret.group())

ret = re.match("[A-Z][a-z]*","Aabcdef")
print(ret.group())

>>>
M
Mnn
Aabcdef
1
2
3
4
5
6
7
8
9
10
11
12
import re


match_obj = re.match("t.+o", "two")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")


>>>
two
1
2
3
4
5
6
7
8
9
10
11
import re

match_obj = re.match("https?", "http")
if match_obj:
print(match_obj.group())
else:
print("匹配失败")


>>>
https
1
2
3
4
5
6
7
8
9
10
11
12
13
import re

# 匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线
ret = re.match("[a-zA-Z0-9_]{6}","12a3g45678")
print(ret.group())

ret = re.match("[a-zA-Z0-9_]{8,20}","1ad12f23s34455ff66")
# {2,} 表示2->无穷
print(ret.group())

>>>
12a3g4
1ad12f23s34455ff66
  • 匹配开头和结尾

  • 代码 功能
    ^ 匹配字符串开头
    $ 匹配字符串结尾
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import re

    # 匹配以数字开头的数据
    match_obj = re.match("^\d.*", "3hello")
    if match_obj:
    # 获取匹配结果
    print(match_obj.group())
    else:
    print("匹配失败")

    >>>
    3hello
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import re
    # 匹配以数字结尾的数据
    match_obj = re.match(".*\d$", "hello5")
    if match_obj:
    # 获取匹配结果
    print(match_obj.group())
    else:
    print("匹配失败")


    >>>
    hello5
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 匹配以数字开头中间内容不管以数字结尾
    match_obj = re.match("^\d.*\d$", "4hello4")
    if match_obj:
    # 获取匹配结果
    print(match_obj.group())
    else:
    print("匹配失败")


    >>>
    4hello4
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # [^指定字符]: 表示除了指定字符都匹配
    import re


    match_obj = re.match("[^aeiou]", "h")
    if match_obj:
    # 获取匹配结果
    print(match_obj.group())
    else:
    print("匹配失败")


    >>>
    h
    代码 功能
    | 匹配左右任意一个表达式
    (ab) 将括号中字符作为一个分组
    \num 引用分组 num 匹配到的字符串
    (?P<name>) 分组起别名
    (?P=name) 引用别名为 name 分组匹配到的字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import re

# 水果列表
fruit_list = ["apple", "banana", "orange", "pear"]

# 遍历数据
for value in fruit_list:
# | 匹配左右任意一个表达式
match_obj = re.match("apple|pear", value)
if match_obj:
print("%s是我想要的" % match_obj.group())
else:
print("%s不是我要的" % value)


>>>
apple是我想要的
banana不是我要的
orange不是我要的
pear是我想要的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re

# 匹配出163、126、qq等邮箱
match_obj = re.match("[a-zA-Z0-9_]{4,20}@(163|126|qq|sina|yahoo)\.com", "hello@163.com")
if match_obj:
print(match_obj.group())
# 获取分组数据
print(match_obj.group(1))
else:
print("匹配失败")


>>>
hello@163.com
163
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import re

# 匹配qq:10567这样的数据,提取出来qq文字和qq号码
match_obj = re.match("(qq):([1-9]\d{4,10})", "qq:10567")

if match_obj:
print(match_obj.group())
# 分组:默认是1一个分组,多个分组从左到右依次加1
print(match_obj.group(1))
# 提取第二个分组数据
print(match_obj.group(2))
else:
print("匹配失败")

>>>
qq
10567
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
match_obj = re.match("<[a-zA-Z1-6]+>.*</[a-zA-Z1-6]+>", "<html>hh</div>")

if match_obj:
print(match_obj.group())
else:
print("匹配失败")

match_obj = re.match("<([a-zA-Z1-6]+)>.*</\\1>", "<html>hh</html>")

if match_obj:
print(match_obj.group())
else:
print("匹配失败")


>>>
<html>hh</div>
<html>hh</html>
1
2
3
4
5
6
7
8
9
10
# 匹配出<html><h1>www.itcast.cn</h1></html>
match_obj = re.match("<([a-zA-Z1-6]+)><([a-zA-Z1-6]+)>.*</\\2></\\1>", "<html><h1>www.itcast.cn</h1></html>")

if match_obj:
print(match_obj.group())
else:
print("匹配失败")

>>>
<html><h1>www.itcast.cn</h1></html>
1
2
3
4
5
6
7
8
9
10
# 匹配出<html><h1>www.itcast.cn</h1></html>
match_obj = re.match("<(?P<name1>[a-zA-Z1-6]+)><(?P<name2>[a-zA-Z1-6]+)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.itcast.cn</h1></html>")

if match_obj:
print(match_obj.group())
else:
print("匹配失败")

>>>
<html><h1>www.itcast.cn</h1></html>
× 请我吃糖~
打赏二维码