Life is short, you need Python.

持续更新!

前言

1、缩进风格统一:

每个缩进层次使用单个制表符(4个空格)
用缩进表示程序块

2、注释

行:#
段:‘’’

3、行连接符 \

4、一切皆对象

一切皆对象

5、变量

每个变量在使用前都必须赋值

1
2
3
4
a = 1
b = c = d = 2 # 同时为多个变量赋值
e, f, g = 1, 2, "zou"
# 两个整型对象 1 和 2 的分配给变量 e 和 f,字符串对象 "zou" 分配给变量 g。

6、保留字

and as assert break class continue
def del elif else except finally
for from False global if import
in is lambda nonlocal not None
or pass raise return try True
while with yield

常用函数

  • 内置

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    1、进制转换
    二进制:0b1010
    八进制:0o76
    十六进制:0x3f
    bin() 将给的参数转换成二进制
    oct() 将给的参数转换成八进制
    int() 将给的参数转换成十进制
    hex() 将给的参数转换成十六进制

    2、数学运算
    abs() 返回绝对值
    a = abs(-10.3) # 10.3
    divmod() 返回商和余数
    divmod(5, 2) # 返回 5 除以 2 的商和余数 (2, 1)
    round() 四舍五入
    pow(a, b) 求a的b次幂, 如果有三个参数. 则求完次幂后对第三个数取余
    sum() 求和
    min() 求最小值
    max() 求最大值

    3、输入输出
    print(num, end="\n") # 输出后换行
    print(num) # 不写时默认换行
    print(num, end="") # 输出后不换行
    r = 4
    v = 4.3332
    print("VOLUME = %.3f, %d" % (v, r)) # VOLUME = 4.333, 4
    a = input() # 返回值是str型
    b = int(input()) # 转化为整型

    4、其它
    eval() # 将字符串当成有效的表达式来求值并返回计算结果

    s = '1 + 2 + 3 * 5 - 2'
    print(eval(s)) #16

    # 字符串中有变量
    x = 1
    print(eval('x + 2')) #3

    # 字符串转字典
    print(eval("{'name':'linux','age':18}")) # {'name':'linux','age':18}

    # 字符串转列表、元组、集合
    # 注意和使用 list()、tuple()、set() 方法转的区别
    str1 = "[1, 2]"
    print(list(str1)) # ['[', '1', ',', ' ', '2', ']']
    print(eval(str1)) # [1, 2]

    # range(start, stop, step)
    返回数字序列,默认从 0 开始,默认以 1 递增,并以指定的数字结束
    x = range(6) # 创建一个从 0 到 5 的数字序列
    for n in x:
    print(n)
    输出:
    0
    1
    2
    3
    4
    5

    id() 返回对象的内存地址
    • 排序
      list.sort() 方法仅被定义在列表中,相反地 sorted() 方法对所有的可迭代序列都有效

      1
      2
      3
      oldlista = [1, 3, 56, 22, 2]
      newlist = sorted(oldlist, reverse=True) # 逆序返回一个新的list
      oldlista.sort(reverse=True) # list本身将被修改
    • 逆序

      1、reverse() 是列表的一种内置方法,用于列表中数据的反转,原地反转

      1
      2
      3
      4
      5
      i = 'abcdef'
      j = list(i) # 字符串转为列表
      j.reverse() # 反转列表,此时 j 为['f', 'e', 'd', 'c', 'b', 'a']

      print(''.join(j)) # 列表转字符串,fedcba

      2、reversed() 可用于列表、元组、字符串、range(n),不会修改原来序列的元素顺序

      应用1:遍历

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      # 列表
      i = [1, 2, 3, 4, 5]
      print([x for x in reversed(i)]) # [5, 4, 3, 2, 1]
      # 元组
      j = (1, 2, 3, 4, 5)
      print([x for x in reversed(j)]) # [5, 4, 3, 2, 1]
      # 字符串
      y = 'abcdef'
      print([x for x in reversed(y)]) # ['f', 'e', 'd', 'c', 'b', 'a']
      # range(n)
      z = range(10)
      print([x for x in reversed(z)]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

      应用2:list()

      可直接将 reversed() 函数逆序返回的迭代器直接转换成列表

      1
      2
      i = 'abcdef'
      print(list(reversed(i))) # ['f', 'e', 'd', 'c', 'b', 'a']
    • 字符串

      1
      2
      3
      4
      5
      str = str.replace('py', 'python') # 替换字符串中的某个片段为另一个片段
      txt = "For only {price:.2f} dollars!" # .2f 表示保留两位小数,和C语言类似
      print(txt.format(price = 49)) # For only 49.00 dollars!
      print("{0:.4f}".format(3.1415926)) # 3.1415
      # 可以使用命名索引 {price}、编号索引{0}、甚至空的占位符 {} 来标识占位符
  • 随机数

    1
    2
    3
    4
    5
    6
    import random
    a = random.choice(range(0, 10)) # 从序列中随机选取一个元素
    b = random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
    c = random.randint(1, 10) # 产生 1 到 10 的一个整型随机数
    d = random.random() # 产生 0 到 1 之间的随机浮点数
    e = random.uniform(1.1, 5.4) # 产生 1.1 到 5.4 之间的随机浮点数,区间可以不是整数
  • 数学

    1
    2
    3
    4
    5
    6
    import math
    b = math.ceil(3.2) # 上取整 4
    c = math.exp(3) # e的3次方
    d = math.sqrt(9) # 平方根 3
    e = math.sin(math.pi / 2) # 1
    f = round(math.pi, 5) # 保留5位小数

运算符

一、算术运算符

/ 除法,运算结果为精确值
// 取整
** 幂

运算符说明 Python运算符 优先级 结合性
小括号 ( ) 19
索引运算符 x[i] 或 x[i1: i2 [:i3]] 18
属性访问 x.attribute 17
乘方 ** 16
按位取反 ~ 15
符号运算符 +(正号)、-(负号) 14
乘除 *、/、//、% 13
加减 +、- 12
位移 >>、<< 11
按位与 & 10
按位异或 ^ 9
按位或 | 8
比较运算符 ==、!=、>、>=、<、<= 7
is 运算符 is、is not 6
in 运算符 in、not in 5
逻辑非 not 4
逻辑与 and 3
逻辑或 or 2
逗号运算符 exp1, exp2 1

二、逻辑运算符

and 布尔"与" - 如果 x 为 False,x and y 返回 x 的值,否则返回 y 的计算值

1
2
3
4
a = 10
b = 20
print(a and b) #20
print(b and a) #10

or 布尔"或" - 如果 x 为 True,x or y 返回 x 的值,否则返回 y 的计算值

1
2
3
4
a = 10
b = 20
print(a or b) #10
print(b or a) #20

not 布尔"非" - 如果 x 为 True,not x 返回 False 。如果 x 为 False,返回 True

1 < 2 < 3,返回 True

‘y’ < ‘x’ == False 等价于 ‘y’ < ‘x’ and ‘x’ == False,至于 ‘x’ == False 的值,由于字符串和 bool 类型没有实现比较方法,所以会进行默认的一致性比较,所以返回 False

数据类型

使用type(a)查看变量的类型

六个标准的数据类型:

  • Number(数字)

  • String(字符串)

  • List(列表)

  • Tuple(元组)

  • Set(集合)

  • Dictionary(字典)

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);

  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。

一、数字型

整型 int

1
2
3
number = 0x3f #十六进制
number2 = 0o17 #八进制
number3 = 0b10 #二进制
  • 转化为十进制

int()可以接收一个或者两个参数,只接收一个参数时,是完整进制表示的数字;接收两个参数时,第一个是数值型字符串,第二个表示第一个参数的进制。

1
2
int('101101', 2) # 二进制转化为十进制
int(0b1010101) # 二进制转化为十进制
  • 转化为二进制

bin()必须传入一个整数,返回一个字符串形式的二进制数

1
2
bin(0o123) #八进制转化为二进制
bin(0x123) #十六进制转化为二进制
  • 转化为八进制
1
2
oct(0b11101) #二进制转化为八进制
oct(123) #十进制转化为八进制
  • 转化为十六进制
1
2
hex(123) #十进制转化为十六进制
hex(0o123) #八进制转化为十六进制

布尔 bool

布尔类型可以当做整数来对待,即 True 相当于整数值 1,False 相当于整数值 0

1
flag = True

浮点 float

复数 complex

二、序列(非数字型)

指字符串、列表、元组、集合和字典

集合和字典不支持索引、切片、相加和相乘操作

通用的操作:

  • 检查元素是否包含在序列中

    1
    2
    3
    4
    value in sequence # 检查某元素是否为序列的成员
    str="abcdefg"
    print('c' in str) # True
    print('c' not in str) # False
  • 序列切片

    切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列。

    序列实现切片操作的语法格式如下:

    1
    sname[start : end : step]

    其中,各个参数的含义分别是:

    • sname:表示序列的名称;
    • start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片;
    • end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度;
    • step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略。
  • 序列相加

    支持多个类型相同的序列使用“+”运算符做相加操作,它会将多个序列进行连接,但不会去除重复的元素。

    类型相同指的是“+”运算符的两侧序列要么都是列表类型,要么都是元组类型,要么都是字符串。

  • 序列相乘

    使用数字 n 乘以一个序列会生成新的序列,其内容为原来序列被重复 n 次的结果

  • 和序列相关的内置函数

    函数 功能
    len() 计算序列的长度,即返回序列中包含多少个元素。
    max() 找出序列中的最大元素。注意,对序列使用 sum() 函数时,做加和操作的必须都是数字,不能是字符或字符串,否则该函数将抛出异常,因为解释器无法判定是要做连接操作(+ 运算符可以连接两个序列),还是做加和操作。
    min() 找出序列中的最小元素。
    list() 将序列转换为列表。
    str() 将序列转换为字符串。
    sum() 计算元素和。
    sorted() 对元素进行排序。
    reversed() 反向序列中的元素。
    enumerate() 将序列组合为一个索引序列,多用在 for 循环中。
    • 字符串转列表

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      a = "ASda"

      l1 = [a]
      l2 = list(a)

      print(l1)
      print(l2)

      ['ASda']
      ['A', 'S', 'd', 'a']
    • 列表转字符串

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      l1 = ["A", "b", "AD"]

      s1 = str(l1)
      s2 = ''.join(l1)

      print(s1)
      print(s2)

      ['A', 'b', 'AD']
      AbAD
    • 元组转字符串

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      l1 = ("A", "b", "AD")

      s1 = str(l1)
      s2 = ''.join(l1)

      print(s1)
      print(s2)

      ('A', 'b', 'AD')
      AbAD
    1
    2
    3
    4
    str="abcdefg"
    print(max(str)) # 找出最大的字符
    print(min(str)) # 找出最小的字符
    print(sorted(str)) # 对字符串中的元素进行排序

(1) 字符串 str
字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始

1
2
3
4
5
print(str[0:-2]) # 输出从下标0到下标-2(不包括)的字符
print(str[2:5]) # 输出从下标2到下标5(不包括)的字符
print(str[2:]) # 输出从下标2开始的所有字符
print(str * 2) # 输出字符串两次,也可以写成 print (2 * str)
print(str + "TEST") # 连接字符串

使用反斜杠 \ 转义特殊字符,如果不想让反斜杠发生转义,可以在字符串前面添加一个 r,表示原始字符串

1
2
print('Ru\noob') #RU
print(r'Ru\noob') #Ru\noob

反斜杠 \ 也可以作为续行符,表示下一行是上一行的延续

(2) 列表 有序 类比数组
列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它可以存储整数、小数、字符串、列表、元组等任何类型的数据

1
2
3
4
5
6
7
8
9
emptylist = [] # 创建一个空列表
list1 = list("hello") #将字符串转换成列表
print(list1) # ['h', 'e', 'l', 'l', 'o']
t = ['a', 'b', 'c', 'd', 'e']
print(t[3]) # 使用下标访问列表元素,输出为 d
print(t[1:]) # ['b', 'c', 'd', 'e']
print(t[:-1]) # ['a', 'b', 'c', 'd']
# 可以接收第三个参数,参数作用是截取的步长
print(t[0:-1:2]) #['a', 'c']
  • 方法

    1、append() 添加元素

    1
    2
    3
    4
    l = ['Python', 'C++', 'Java']
    t = ('JavaScript', 'C#', 'Go')
    l.append(t) # 追加元组,整个元组被当成一个元素
    print(l) # ['Python', 'C++', 'Java', ('JavaScript', 'C#', 'Go')]

    2、extend() 添加元素

    extend() 和 append() 的不同之处在于:extend() 不会把列表或者元祖视为一个整体,而是把它们包含的元素逐个添加到列表中

    1
    2
    3
    4
    l = ['Python', 'C++', 'Java']
    t = ('JavaScript', 'C#', 'Go')
    l.entend(t) # 追加元组,元祖被拆分成多个元素
    print(l) # ['Python', 'C++', 'Java', 'C', 'JavaScript', 'C#', 'Go']

    3、insert() 插入元素

    当插入列表或者元组时,insert() 会将它们视为一个整体,作为一个元素插入到列表中,这一点和 append() 是一样的。

    1
    2
    3
    l = ['Python', 'C++', 'Java']
    l.insert(1, ['Ruby', 'SQL']) # 插入列表,整个列表被当成一个元素
    print(l) # ['Python', ['Ruby', 'SQL'], 'C++', 'Java']

    4、del:根据索引值删除元素

    1
    2
    3
    4
    5
    lang = ["Python", "C++", "Java", "PHP", "Ruby", "MATLAB"]
    del lang[2]
    print(lang) # ['Python', 'C++', 'PHP', 'Ruby', 'MATLAB']
    del lang[1: 4] # 删除中间一段连续的元素
    print(lang) # ['Python', 'MATLAB']

    5、pop():根据索引值删除元素

    1
    2
    3
    4
    5
    nums = [40, 36, 89, 2, 36, 100, 7]
    nums.pop(3)
    print(nums) # [40, 36, 89, 36, 100, 7]
    nums.pop()
    print(nums) # [40, 36, 89, 36, 100]

    6、remove():根据元素值进行删除

    只会删除第一个和指定值相同的元素,而且必须保证该元素是存在的

    1
    2
    3
    nums = [40, 36, 89, 2, 36, 100, 7]
    nums.remove(36)
    print(nums) # [40, 89, 2, 36, 100, 7]

    7、list.clear():删除列表所有元素

(3) 元组 有序
元组与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开
元组可以存储整数、实数、字符串、列表、元组等任何类型的数据,并且在同一个元组中,元素的类型可以不同
当创建的元组中只有元素时,该元素后面必须要加一个逗号,否则会忽视元组的创建

1
2
3
4
5
6
t = ('a', 1, 2.22, 'css', [1, '2'], 'asd')
tup1 = () #空元组
tup2 = (20,) #一个元素,需要在元素后添加逗号
dict1 = {'a':100, 'b':42, 'c':9}
tup3 = tuple(dict1) #将字典转换成元组
print(tup3) # ('a', 'b', 'c')

(4) 集合 无序
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典
可以存储数字、字符串、元组、布尔类型(True 和 False)

1
2
3
4
5
6
7
8
9
10
11
12
sites = {'google', 'baidu', 'facebook', 'google'}
print(sites) # 输出集合,重复的元素被自动去掉
a = set('abcd')
a.add('e')
print(a) # 包含 abcde
b = set('efghij')
b.remove('j')
print(b) # 包含 efghi
print(a - b) # 包含 abcd,取 a 中 b 没有的元素
print(a | b) # 包含 abcdefghi,取两集合全部的元素
print(a & b) # {'e'},取两集合公共的元素
print(a ^ b) # 包含 abcdfghi,取集合 a 和 b 中不属于 a&b 的元素

(5) 字典 无序
字典是一种映射类型,用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合
键(key)必须使用不可变类型,必须是唯一的
创建空字典使用 { }

1
2
3
dic = {'1': 'a', 2: 'b', (3.1, 3.2): [3.3, 3.4]}
print(dic.keys()) #输出所有键
print(dic.values()) #输出所有值
  • 删除键值对
    如果要删除字典中的键值对,使用 del 语句。例如:

    1
    2
    3
    4
    a = {'数学': 95, '语文': 89, '英语': 90}
    del a['语文']
    del a['数学']
    print(a) # {'英语': 90}
  • 判断字典中是否存在指定键值对

    1
    2
    3
    a = {'数学': 95, '语文': 89, '英语': 90}
    # 判断 a 中是否包含名为'数学'的key
    print('数学' in a) # True
  • 字典推导式
    enumerate(sequence, [start]) 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中,start 为起始位置的值,默认为 0​。

    1
    2
    3
    4
    5
    6
    7
    list1 = ["A", "B", "C", "D", "E"]
    dict1 = {key: value for key, value in enumerate(list1, 1)}
    print(dict1) # {1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E'}

    dict2 = {"a": 1, "b": 2, "c": 3}
    dict3 = {value: key for key, value in dict2.items()}
    print(dict3) # {1: 'a', 2: 'b', 3: 'c'}
    1
    2
    3
    # 对字典使用 enumerate()
    dict2 = {"a": 1, "b": 2}
    dict3 = {value: key for key, value in enumerate(dict2)} # {'a': 0, 'b': 1, 'c': }

数据类型转换

显式类型转换

1
2
3
4
5
6
int(x) # 将x转换为一个整数,浮点数保留整数部分
float(x) # 将x转换到一个浮点数
str(x) # 将对象 x 转换为字符串
tuple(s) # 将序列 s 转换为一个元组
list(s) # 将序列 s 转换为一个列表
set(s) # 将序列 s 转换为一个集合

条件控制

1
2
3
4
5
6
7
age = int(input("请输入年龄"))
if age <= 10:
print("年龄小于10")
elif age <= 20:
print("年龄大于10小于20")
else:
print("年龄大于20")

循环语句

  • while 循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    i = 1
    n = 10
    sum = 0
    while i <= n:
    sum += i
    i += 1
    else:
    print("%d大于10" % i)
    print("1到%d之和为: %d" % (n, sum))
  • for 循环
    可以遍历任何可迭代对象,如一个列表或者一个字符串

    1
    2
    3
    languages = ["C", "C++", "Java", "Python"]
    for x in languages:
    print(x)
  • else 语句
    跟在 while 和 for 循环语句的后面使用,和它们平级,作用为当==循环条件不再成立==时,可以运行一个代码块。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 检查列表中是否含有奇数
    nlist = [100, 120, 60, 123, 456]

    for n in nlist:
    if n % 2 != 0:
    print("Not all even!")
    break
    else:
    print("All even")
  • range() 函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    range(10) # [0, 10)
    range(0, 5) # [0, 5)
    range(0, 8, 2) # 2为步长

    l1 = list(range(10)) # 创建一个列表

    # 结合range()和len()函数以遍历一个序列的索引
    a = ['Google', 'Baidu', 'Yahoo', 'Taobao', 'Tencent']
    for i in range(len(a)):
    print(a[i])

函数

  • 参数传递:
    不可变类型:类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
    可变类型:类似 C++ 的引用传递,如列表、字典。如 fun(la),将 la 真正的传过去,修改后 fun 外部的 la 也会受影响。

  • 关键字参数
    使用关键字参数允许函数调用时参数的顺序与声明时不一致

  • 默认参数
    如果没有传递参数,则会使用默认参数
    默认参数必须放在参数列表的最后面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    def max(a, b, c=10): #c为默认参数
    print("默认参数c = ", c)
    if a > b:
    return a
    else:
    return b


    print("较大值 = ", max(b=1, a=5)) #关键字参数
  • 匿名函数 lambda

    x: x * x``` 实际上就是:
    1
    2
    3
    4

    ```python
    def f(x):
    return x * x

    关键字lambda表示匿名函数,冒号前面的x表示函数参数。
    匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
    用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:

    1
    2
    3
    4
    f = lambda x: x ** 2


    print(f(4)) # 16
  • 可变参数
    允许你传入 0 个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple

    1
    2
    3
    4
    5
    6
    7
    8
    def calc(*numbers):
    sum = 0
    for n in numbers: # 函数内部,参数`numbers`接收到的是一个元组
    sum = sum + n * n
    return sum


    print(calc(1, 2)) # 5
  • 关键字参数

    允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

    1
    2
    3
    4
    5
    def calc(**numbers):
    return numbers


    print(calc(name=1)) # {'name': 1}

模块

import 与 from…import

在 python 用 import 或者 from…import 来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: from somemodule import *

面向对象

1、类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响
2、方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据
3、通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节
4、和静态语言不同,Python 允许对实例变量绑定任何数据,也就是说,对于两个实例变量,虽然它们都是同一个类的不同实例,但拥有的变量名称都可能不同
5、由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把nameage等属性绑上去
6、注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身

1
2
3
4
5
6
7
8
9
10
11
12
class ren(object):
def __init__(self, name, age):
self.name = name # 实例属性
self.age = age

def print_age(self):
print(self.name, self.age)


wang = ren("wang", 20)
he = ren("he", 30)
he.num = 2 # 为实例 he 添加独有属性,而不会影响类和其它实例

私有属性

1、把属性的名称前加上两个下划线__,就变成了一个私有变量(private)
2、变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____age__这样的变量名
3、不能直接访问__name是因为 Python 解释器对外把__name变量改成了_ren__name,所以,仍然可以通过_ren__name来访问__name变量

1
2
3
4
5
6
7
8
9
10
11
12
13
class ren(object):
def __init__(self, name, age):
self.__name = name # 私有属性
self.__age = age

def print_age(self):
print(self.__name, self.__age)


he = ren("he", 30)
print(he._ren__name) # 输出 he,因为 _ren__name 是私有属性
he.__name = 'he2' # __name 是一个普通属性
print(he.__name) # he2

继承

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
class dog:
# 基本属性
name = ''
age = 3
# 私有属性
__weight = 10

def __init__(self, name, age, __weight): # self 相当于 this
self.name = name
self.age = age
self.__weight = __weight

def bark(self):
print("姓名:%s 年龄:%d 体重:%d" % (self.name, self.age, self.__weight), end=" ")


x = dog("wang", 20, 100)
x.bark()
print()

class hashiqi(dog):
iq = 250

def __init__(self, name, age, __weight, iq):
# 调用父类的构造函数,相当于 super(name, age, __weight)
dog.__init__(self, name, age, __weight)
self.iq = iq

# 重写父类的方法
def bark(self):
dog.bark(self)
print("智商:%d" % self.iq)


y = hashiqi("he", 21, 50, 520)
y.bark()

# 输出
姓名:wang 年龄:20 体重:100
姓名:he 年龄:21 体重:50 智商:520

多态

当我们定义一个类的时候,我们实际上就定义了一种数据类型。我们定义的数据类型和 Python 自带的数据类型没什么两样

1
2
3
a = list() # a 是 list 类型
b = Animal() # b 是 Animal 类型
c = Dog() # c 是 Dog 类型
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
class Animal(object):
def run(self):
print('Animal is running...')


class Dog(Animal):
def run(self):
print('Dog is running...')


class Cat(Animal):
def run(self):
print('Cat is running...')


def run_twice(animal):
animal.run()
animal.run()


a = Animal()
d = Dog()
c = Cat()


# Dog 可以看成 Animal,但 Animal 不可以看成 Dog
print('a is Animal?', isinstance(a, Animal)) # True
print('a is Dog?', isinstance(a, Dog)) # False
print('a is Cat?', isinstance(a, Cat)) # False

print('d is Animal?', isinstance(d, Animal)) # True
print('d is Dog?', isinstance(d, Dog)) # True
print('d is Cat?', isinstance(d, Cat)) # False

run_twice(c)
'''
Cat is running...
Cat is running...
'''

调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的

“开闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

类属性

实例属性属于各个实例所有,互不干扰;
类属性属于类所有,所有实例共享一个属性;
不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。

1
2
3
4
5
6
7
8
9
10
11
class ren(object):
name = "default" # 类属性 name


he = ren() # 创建实例 he
print(he.name) # default
print(ren.name) # default
he.name = "he" # 给实例绑定实例属性 name
print(he.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的 name 属性,输出 he
del he.name # 删除实例的 name 属性
print(he.name) # default

实例方法、类方法、静态方法

1、实例方法需要传入 self,类方法需要传入 cls 参数,静态方法无需传入 self 参数或者是 cls 参数(但不等同于不能传入参数)。
2、当调用实例方法(instance method)时,self 参数指向的是刚刚实例化出的 my_class 实例对象。
3、当调用类方法(class method)时,cls 参数指向的是一开始定义的 MyClass 类对象(注意不是实例对象)。
4、类方法也算一种实用的技巧,简单描述之:“类方法让类模板具有记忆力”。
5、静态方法有点像附属于类对象的“工具”。与普通函数不同,调用静态方法时,只能通过类对象(或者实例对象)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class MyClass(object):
# 实例方法
def instance_method(self):
print('instance method called', self)

# 类方法
@classmethod
def class_method(cls):
print('class method called', cls)

# 静态方法
@staticmethod
def static_method():
print('static method called')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Man:
id = 0 # 类变量
def __init__(self, name):
self.name = name
self.id = self.id_number()

@classmethod
def id_number(cls):
cls.id += 1
return cls.id

a = Man('A')
print(a.id)
b = Man('B')
print(b.id)

1
2

文件

模式 可做操作 若文件不存在 是否覆盖文件原来内容
r 只读 报错 ——
r+ 可读、可写 报错
w 只写 创建
w+ 可读、可写 创建
a 只写 创建 否,追加写
a+ 可读、可写 创建 否,追加写

常用算法

1
2
3
4
5
6
7
8
9
10
11
# 分解质因数
n = int(input("请输入一个正整数:"))
print("{} = ".format(n), end="")
for i in range(2, n + 1):
while (n % i == 0):
if i == n:
print(i)
break
else:
print("{} * ".format(i), end="")
n /= i