Python 基础总结

news2024/12/23 22:23:19

title: Python 基础总结
date: 2023-07-19 10:51:55
tags:

  • Python
    categories:
  • Python
    cover: https://cover.png
    feature: false

1. print() 函数

1.1 基础使用

# 输出数字
print(23)
print(11.323)

# 输出字符串
print('你好')
print("你好")

# 输出表达式
print(3 * 3)
print(5 % 2)

# 输出到文件中
fp = open('D://text.txt', 'a+')  # a+ 表示文件不存在则创建, 存在则在内容后面追加
print('test', file=fp)
print('++', file=fp)
fp.close()

# 不换行输出
print('hello', 'world')

23
11.323
你好
你好
9
1
hello world

1.2 转义字符与原字符

print('hello\nworld')  # 打印换行
# \t 打印空格 1 位, 因为一个制表位为 4 个字符, 而 \t 只会补满制表符, hell 占一个制表符, ooo 占一个制表符的 3 位, \t 补满剩下的 1 位
print('hellooo\tworld')
print('helloooo\tworld')  # \t 打印空格 4 位, helloooo 占满 2 个制表符, \t 新开一个制表符, 4 位
print('hello\rworld')  # world 对 hello 进行覆盖
print('hello\bworld')  # 退格 1 位, o 被退位

# 原字符, 不希望转义字符起作用, 在前面加上 r/R
print(r'hello\nworld')

1.3 二进制及编码

print(chr(0b100111001011000))
print(chr(0b110101001))


Ʃ

1.4 标识符与保留字

import keyword

print(keyword.kwlist)

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

1.5 变量

一个变量由三部分组成,标识(id)、类型(type)、值

name = '张三'
print(name)
print('标识', id(name))
print('类型', type(name))
print('值', name)

name = '李四'
print(name)

张三
标识 1765751614576
类型 <class ‘str’>
值 张三
李四

1.6 数据类型

1.6.1 整数类型 int

可以表示正数、负数、零。默认进制是十进制,0b 表示二进制、0o 表示八进制、0x 表示十六进制

n1 = 10
n2 = -10
n3 = 0
print(n1, type(n1))
print(n2, type(n2))
print(n3, type(n3))

print('十进制', 118)
print('二进制', 0b10101111)  # 以 ob 开头
print('八进制', 0o176)  # 以 0o 开头
print('十六进制', 0x1EAF)  # 以 0x 开头

10 <class ‘int’>
-10 <class ‘int’>
0 <class ‘int’>
十进制 118
二进制 175
八进制 126
十六进制 7855

1.6.2 浮点数类型 float

由整数和小数部分组成,存储时可能出现小数部分不精确的情况

a = 3.1415
print(a, type(a))

n1 = 1.1
n2 = 2.2
print(n1 + n2)

3.1415 <class ‘float’>
3.3000000000000003

可以引入 Decimal 模块来进行精确运算

from decimal import Decimal

print(Decimal('1.1') + Decimal('2.2'))

3.3

1.6.3 布尔类型 bool

True 和 False,首字母为大写

f1 = True
f2 = False
print(f1, type(f1))
print(f2, type(f2))

# 转成整数计算
print(f1 + 1)  # True 表示 1
print(f2 + 1)  # False 表示 0

True <class ‘bool’>
False <class ‘bool’>
2
1

1.6.4 字符串类型 str

字符串又被称为不可变的字符序列,可以用单引号 ' '、双引号 " "、三引号 ''' '''""" """ 来表示,单引号和双引号定义的字符串必须在一行,多引号定义的字符串可以分布在连续的多行

str1 = '你好'
str2 = "你好"
print(str1, type(str1))
print(str2, type(str2))

str3 = '''hello
world'''
print(str3, type(str3))
str4 = """hello
world"""
print(str4, type(str4))

你好 <class ‘str’>
你好 <class ‘str’>
hello
world <class ‘str’>
hello
world <class ‘str’>

1.6.5 数据类型转换

  • str():将其他类型转成字符串
  • int():将其他类型转成整数类型
  • float():将其他类型转成浮点数类型
name = '张三'
age = 18
print(type(name), type(age))
# print('我叫' + name + '今年' + age + '岁')  # error
print('我叫' + name + '今年' + str(age) + '岁')

# str() 函数, 将其他类型转成 str
s1 = 128
s2 = 98.7
s3 = True
print(type(str(s1)), type(str(s2)), type(str(s3)))

# int() 函数, 将其他类型转成 int
s4 = '23'
s5 = '23.2'
print(int(s2), type(int(s2)))  # float 转成 int 类型, 只保留整数部分
print(int(s3), type(int(s3)))  # bool 转成 int 类型, True 为 1, False 为 0
print(int(s4), type(int(s4)))  # str 转成 int 类型, 字符串要为整数数字串
# print(int(s5), type(int(s5)))  # error

# float() 函数, 将其他类型转成 float
print(float(s1), type(float(s1)))
print(float(s3), type(float(s3)))
print(float(s4), type(float(s4)))
print(float(s5), type(float(s5)))

<class ‘str’> <class ‘int’>
我叫张三今年18岁
<class ‘str’> <class ‘str’> <class ‘str’>
98 <class ‘int’>
1 <class ‘int’>
23 <class ‘int’>
128.0 <class ‘float’>
1.0 <class ‘float’>
23.0 <class ‘float’>
23.2 <class ‘float’>

1.7 注释

  • #:单行注释
  • ''' '''""" """:多行注释
  • # coding:utf-8:中文编码注释说明,指定源码的文件格式

2. input() 函数

2.1 基础使用

word = input('输入一个词: ')
print(word)

输入一个词: 你好
你好

需要注意的是,输入的值为 str 类型,要计算的话需要转成数字或浮点数类型进行计算

a = input('请输入一个加数: ')
b = input('请输入一个加数: ')
print(type(a), type(b))
print(a + b)

print(int(a) + int(b))

请输入一个加数: 10
请输入一个加数: 20
<class ‘str’> <class ‘str’>
1020
30

或者直接在输入时进行转换

a = int(input('请输入一个加数: '))
print(type(a))

请输入一个加数: 10
<class ‘int’>

2.2 运算符

2.2.1 算数运算符

  • +:加法
  • -:减法
  • *:乘法
  • /:除法
  • //:整除
  • %:取余
  • **:幂运算
a = 10
b = 3
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a // b)
print(a % b)
print(a ** b)

13
7
30
3.3333333333333335
3
1
1000

当存在负数时,整除和取余运算需要额外思考一下

# 一正一负整除, 向下取整
print(9 // -4)
print(-9 // 4)
# 一正一负取余, 余数 = 被除数 - 除数 * 商
print(9 % -4)
print(-9 % 4)

-3
-3
-3
3

2.2.2 赋值运算符

1、赋值顺序从右到左

a = 3 + 4
print(a)

7

2、支持链式赋值,变量的引用都指向同一个地址

a = b = c = 20
print(a, id(a))
print(b, id(b))
print(c, id(c))

20 140728618902920
20 140728618902920
20 140728618902920

3、支持参数赋值,进行除法运算时,会转成 float 类型,因为除法可能存在小数

a = 30
a += 10
print(a)
a *= 3
print(a, type(a))
a /= 2
print(a, type(a))

40
120 <class ‘int’>
60.0 <class ‘float’>

4、支持系列解包赋值

a, b, c = 10, 20.3, 'ss'
print(a, type(a))
print(b, type(b))
print(c, type(c))

10 <class ‘int’>
20.3 <class ‘float’>
ss <class ‘str’>

2.2.3 比较运算符

对表达式大小、真假进行比较,结果是 bool 类型。== 比较的是值,isis not 比较的是标识

a, b = 10, 20
print(a > b)
print(a <= b)

# 一个变量由 标识、类型、值 三部分组成, == 比较的是值, is 比较的是标识, is not 即标识不相等
print(a == b)
print(a != b)

c = 10
print(a == c, id(a))
print(a is c, id(c))
print(a is not c)

list1 = [11, 22, 33]
list2 = [11, 22, 33]
print(list1 == list2, id(list1))
print(list1 is list2, id(list2))
print(list1 is not list2)

False
True
False
True
True 140728618902600
True 140728618902600
False
True 2933228983616
False 2933230769856
True

2.2.4 布尔运算符

  • and:且
  • or:或
  • not:非,取反
  • in:是否存在
  • not in:是否不存在
a, b = 1, 2
print(a == 1 and b != 2)
print(a == 1 or b != 2)

f1 = True
f2 = False
print(not f1)

s1 = 'he'
s2 = 'hello'
print(s1 in s2)
print(s1 not in s2)

False
True
False
True
False

2.2.5 位运算符

  • &:位与,对应位数都是 1,结果位数才为 1,其他则为 0
  • |:位或,对应位数都是 0,结果位数才为 0,其他则为 1
  • <<:左移位运算符,高位溢出舍弃,低位补 0,相当于除 2
  • >>:右移位运算符,低位溢出舍弃,高位补 0,相当于乘 2
# 0000 0100
# 0000 1000
a, b = 4, 8
# 0000 0000
print(a & b)
# 0000 1100
print(a | b)
# 0000 0001
print(a >> 2)
# 0001 0000
print(a << 2)

0
12
1
16

2.2.6 运算符优先级

先算算数运算(先乘除、后加减);然后算位运算;再算比较运算;再算布尔运算;最后赋值

  1. **
  2. *、/、//、%
  3. +、-
  4. <<、>>
  5. &
  6. |
  7. >、<、>=、<=、==、!=
  8. and
  9. or
  10. =

3 程序的组织结构

3.1 顺序结构

从上到下顺序的执行代码,中间没有任何判断和跳转,直到程序结束

print('1. 把冰箱门打开')
print('2. 把大象放进去')
print('3. 把冰箱门关上')
  1. 把冰箱门打开
  2. 把大象放进去
  3. 把冰箱门关上

3.2 对象的布尔值

Python 一切皆对象,所有对象都有一个布尔值,使用内置函数 bool() 可以获取对象的布尔值

以下对象的布尔值为 False

print(bool(False))  # False
print(bool(0))  # 整数 0
print(bool(0.0))  # 浮点数 0.0
print(bool(None))  # 空
print(bool(''))  # 空串
print(bool([]))  # 空列表
print(bool(list()))  # 空列表
print(bool(()))  # 空元组
print(bool(tuple()))  # 空元组
print(bool({}))  # 空字典
print(bool(dict()))  # 空字典
print(bool(set()))  # 空集合

False
False
False
False
False
False
False
False
False
False
False
False

剩下的其他所有的对象的布尔值都为 True

3.3 选择结构

3.3.1 单选择

money = 1000
s = int(input('请输入取款金额: '))
if money >= s:
    money -= s
    print('余额为', money)

请输入取款金额: 500
余额为 500

请输入取款金额: 1200

3.3.2 双选择

money = 1000
s = int(input('请输入取款金额: '))
if money >= s:
    money -= s
    print('余额为', money)
else:
    print('余额不足')

请输入取款金额: 1200
余额不足

3.3.3 多选择

score = int(input('请输入成绩: '))
if 90 <= score <= 100:
    print('优秀')
elif 80 <= score < 90:
    print('良好')
elif 70 <= score < 80:
    print('一般')
elif 60 <= score < 70:
    print('及格')
elif score < 60:
    print('不及格')
else:
    print('成绩不在范围内')

请输入成绩: 78
一般

请输入成绩: 67
及格

请输入成绩: 102
成绩不在范围内

3.3.4 嵌套选择

money = float(input('请输入购物金额: '))
vip = input('你有会员吗?y/n')
if vip == 'y':
    if money >= 200:
        print('八折')
    elif money < 200:
        print('九折')
    else:
        print('不打折')
else:
    if money >= 200:
        print('九五折')
    else:
        print('不打折')

请输入购物金额: 200
你有会员吗?y/ny
八折

请输入购物金额: 150
你有会员吗?y/ny
九折

3.3.5 条件表达式

当 if 为 true 时,执行左边的,else 则执行右边的

a = int(input('输入第一个整数: '))
b = int(input('输入第二个整数: '))
print(str(a) + '大于等于' + str(b) if a >= b else str(a) + '小于' + str(b))

输入第一个整数: 20
输入第二个整数: 10
20大于等于10

输入第一个整数: 10
输入第二个整数: 20
10小于20

3.3.6 pass 语句

什么都不做,只是一个占位符,用于需要写语句的地方,让编辑器不报错

vip = input('你有会员吗?y/n')
if vip == 'y':
    pass
else:
    pass

3.4 range() 函数

用于生成一个整数序列

  • range(stop):创建一个 [0, stop] 之间的整数序列,步长为 1
  • range(start, stop):创建一个 [start, stop] 之间的整数序列,步长为 1
  • range(start, stop, step):创建一个 [start, stop] 之间的整数序列,步长为 step
r = range(10)
print(r, type(r))
print(list(r))
print(10 in r)
print(10 not in r)

print(list(range(5, 10)))
print(list(range(5, 10, 2)))

range(0, 10) <class ‘range’>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
False
True
[5, 6, 7, 8, 9]
[5, 7, 9]

优点:不管 range 对象表示的整数序列有多长,所有 range 对象占用的内存空间都是相同的,仅仅存储了 start、stop、step,只有当用到 range 对象的时候,才会去计算序列中的相关元素

3.5 循环结构

3.5.1 while 循环

result = 0
i = 0
while i < 5:
    result += i
    print(result)
    i += 1
print('和为: ', result)

0
1
3
6
10
和为: 10

3.5.2 for-in 循环

for item in 'python':
    print(item)

p
y
t
h
o
n

for i in range(5):
    print(i)

0
1
2
3
4

不需要自定义变量可以写为 _

for _ in range(5):
    print("hello")

hello
hello
hello
hello
hello

3.5.3 流程控制语句

  • break:用于结束循环结构
  • continue:用于结束当前循环,进入下一次循环

3.5.4 else 语句

# for a in range(3):
a = 0
while a < 3:
    password = input('请输入密码: ')
    if password == '123':
        print('密码正确')
    else:
        print('密码错误')
    a += 1
else:
    print('你的密码已输入错误三次, 请 1 分钟再试')

请输入密码: 888
密码错误
请输入密码: 888
密码错误
请输入密码: 888
密码错误
你的密码已输入错误三次, 请 1 分钟再试

3.5.5 嵌套循环

for i in range(4):
    for j in range(4):
        print('*', end='\t')  # 不换行输出
    print()

* * * *
* * * *
* * * *
* * * *

嵌套循环中的 break 和 continue 只控制本层循环,不影响外层循环

4. 列表

变量可以存储一个元素,而列表是一个大容器,可以存储 N 多个元素,列表相当于其他语言中的数组

特点:

  • 元素有序
  • 索引映射唯一一个数据
  • 可以存储重复数据
  • 可以存储任意数据类型
  • 根据需要动态分配和回收内存

4.1 创建

  • [value...]:中括号
  • list(iterator):内置函数
l1 = ['hello', 'world', 98]
print(id(l1))
print(type(l1))
print(l1)

l2 = list(['hello', 'world', 98])
print(l2)
l3 = list('python')
print(l3)

2591304603584
<class ‘list’>
[‘hello’, ‘world’, 98]
[‘hello’, ‘world’, 98]
[‘p’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’]

4.2 操作

4.2.1 查询

1、获取单个元素

  • index(value, start, stop):获取列表中指定元素的索引,元素不存在会报错
  • [index]:通过索引,获取列表中的单个元素,负数表示逆向获取
l1 = ['hello', 'world', 98, 'hello']
print(l1.index('hello'))
print(l1.index('python')) # error
print(l1.index('hello', 1))

# 负数为逆向获取
print(l1[-3])
# 正数即正向获取
print(l1[2])

0
3
world
98

2、获取多个元素,切片操作,[start:stop:step],任何一个参数都可以省略,步长为负数同样表示逆向获取

l2 = l1[0:2:1]
print(l1, id(l1), l2, id(l2))
# 任何一个参数都可省略
print(l1[0:2], l1[0:2:])
print(l1[:2:2])
print(l1[0::2])
print(l1[0:])

[‘hello’, ‘world’, 98, ‘hello’] 2507973351296 [‘hello’, ‘world’] 2507974416384
[‘hello’, ‘world’] [‘hello’, ‘world’]
[‘hello’]
[‘hello’, 98]
[‘hello’, ‘world’, 98, ‘hello’]

3、判断及遍历

  • value in list:判断是否存在
  • value not in list:判断是否不存在
  • for var in list:遍历 list

4.2.2 添加

  • append(value):向列表末尾添加一个元素
  • extend(list):向列表末尾至少添加一个元素
  • insert(index, value):在列表的任意位置添加一个元素
  • 切片,在列表的任意位置添加至少一个元素
l1 = []
l1.append(1)
print(id(l1))
l1.append(2)
print(l1, id(l1))

l2 = [3, 4]
l1.append(l2)
l1.extend(l2)
print(l1)

l1.insert(1, 10)
print(l1)

l3 = [True, False]
l1[1:] = l3
print(l1)

2271766206336
[1, 2] 2271766206336
[1, 2, [3, 4], 3, 4]
[1, 10, 2, [3, 4], 3, 4]
[1, True, False]

4.2.3 删除

  • remove(value):移除一个元素,有重复元素移除第一个,移除元素不存在则报错
  • pop(index):删除一个指定索引位置的元素,索引不存在则报错,不指定则删除末尾元素
  • 切片,一次至少删除一个元素
  • clear():清空列表
  • del:删除列表
l1 = [10, 20, 30, 40, 50, 20]
l1.remove(20)
print(l1)
l1.pop()
print(l1)
l2 = l1[1:3:]
print(l1, l2)
l1.clear()
print(l1)
del l1
print(l1)  # error

[10, 30, 40, 50, 20]
[10, 30, 40, 50]
[10, 30, 40, 50] [30, 40]
[]

4.2.4 修改

  • 为指定索引的元素赋一个新值
  • 为指定的切片赋一个新值
l1 = [10, 20, 30, 40]
l1[2] = 100
print(l1)
l1[3:] = [2, 3]
print(l1)

[10, 20, 100, 40]
[10, 20, 100, 2, 3]

4.2.5 排序

  • sort():默认从小到大排序,指定 reverse=True 可以进行降序排序,默认为 False
  • sorted():内置函数,用法与上同,原列表不发生改变
l1 = [20, 10, 50, 30]
l1.sort()
print(l1)
l1.sort(reverse=True)
print(l1)

l2 = sorted(l1)
print(l2)
l3 = sorted(l1, reverse=True)
print(l3)

[10, 20, 30, 50]
[50, 30, 20, 10]
[10, 20, 30, 50]
[50, 30, 20, 10]

4.3 列表生成式

l1 = [i*i for i in range(10)]

  • i * i:表示列表元素的表达式
  • i:自定义变量
  • range(10):可迭代对象
l1 = [i * i for i in range(10)]
print(l1)

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

5. 字典

Python 内置的数据结构之一,与列表一样是一个可变序列,以键值对的方式存储数据,但键是不可变的。字典是一个无序的序列,这里的序指的是排列顺序,即输出的顺序与输入的顺序一致

特点:

  • key 不能重复,值可以重复
  • 字典中的元素是无序的
  • key 必须是不可变对象
  • 可以根据需要动态的伸缩
  • 会浪费较大的内存,是一种使用空间换时间的数据结构

5.1 创建

  • {key:value...}:花括号
  • dict():内置函数
d1 = {'张三': 100, '李四': 200}
print(d1)
d2 = dict(name='张三', age=28)
print(d2)

{‘张三’: 100, ‘李四’: 200}
{‘name’: ‘张三’, ‘age’: 28}

5.2 操作

5.2.1 获取

  • [key]:获取对应键的值,键不存在则报错
  • get(key):获取对应键的值,键不存在则返回 None,并且可以通过参数设置默认返回的 value
d1 = {'张三': 100, '李四': 200}
print(d1['张三'])
print(d1.get('张三'))

print(d1[2])  # error
print(d1.get(2))
print(d1.get(2, 99))

100
100
None
99

判断与遍历

  • key in dict:判断是否存在
  • key not in dict:判断是否不存在
  • for key in dict:遍历字典的 key

5.2.2 增删改

1、新增:dict[key] = value

2、修改:dict[key] = newValue

3、删除

  • 删除单个 key:del dict[key]
  • 清空字典:clear()
  • 删除字典:del dict
d1 = {'张三': 100, '李四': 200}
d1['王五'] = 300
print(d1)

d1['王五'] = 333
print(d1)

del d1['王五']
print(d1)

d1.clear()
print(d1)

del d1
print(d1)  # error

{‘张三’: 100, ‘李四’: 200, ‘王五’: 300}
{‘张三’: 100, ‘李四’: 200, ‘王五’: 333}
{‘张三’: 100, ‘李四’: 200}
{}

5.2.3 获取字典视图

  • keys():获取字典的所有 key
  • values():获取字典的所有 value
  • items():获取字典的所有 key:value 对
d1 = {'张三': 100, '李四': 200}
print(d1.keys(), type(d1.keys()))
print(list(d1.keys()))
print(d1.values(), type(d1.values()))
print(list(d1.values()))
print(d1.items(), type(d1.items()))
print(list(d1.items()))

dict_keys([‘张三’, ‘李四’]) <class ‘dict_keys’>
[‘张三’, ‘李四’]
dict_values([100, 200]) <class ‘dict_values’>
[100, 200]
dict_items([(‘张三’, 100), (‘李四’, 200)]) <class ‘dict_items’>
[(‘张三’, 100), (‘李四’, 200)]

5.3 字典生成式

d1 = {item: price for item, price in zip(items, price)}

  • item: price:字典的键值对元素
  • item, price:自定义变量
  • zip(items, price):内置函数,用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回这些元组组成的列表
items = ['fruit', 'book']
price = [100, 200]
l1 = zip(items, price)
print(l1, list(l1))

d1 = {item: price for item, price in zip(items, price)}
print(d1)

<zip object at 0x000002AA57190C40> [(‘fruit’, 100), (‘book’, 200)]
{‘fruit’: 100, ‘book’: 200}

6. 元组

Python 的内置数据结构之一,是一个不可变序列

6.1 可变序列与不可变序列

可变序列:列表、字典。可以对序列执行增、删、改操作,对象地址不发生改变

不变序列可变序:字符串、元组。没有增、删、改的操作

6.2 创建

  • (value1, value2):小括号,小括号可省略
  • (value,):只有一个元素时,以 , 结尾,小括号可省略
  • tuple():内置函数
t1 = ('python', 99)
print(t1, type(t1))
t2 = ('python',)
print(t2, type(t2))

t3 = 'python',
print(t3, type(t3))

t4 = tuple(('python', 'world', 98))
print(t4, type(t4))

(‘python’, 99) <class ‘tuple’>
(‘python’,) <class ‘tuple’>
(‘python’,) <class ‘tuple’>
(‘python’, ‘world’, 98) <class ‘tuple’>

6.3 为什么将元组设计为不可变序列

在多任务环境下,同时操作对象时不需要加锁,因此,在程序中尽量使用不可变序列

需要注意的是,元组存储的是对象的引用,如果元组中对象本身是不可变对象,则不能再引用其他对象;如果对象是可变对象,则可变对象的引用不可改变,但数据可以改变

6.4 遍历

for item in t4:
    print(item)

python
world
98

7. 集合

Python 语言提供的内置数据结构,与列表、字典一样都属于可变类型的序列,集合是没有 value 的字典

7.1 创建

  • {value...}:花括号
  • set():内置函数
s1 = {10, 20, 30, 40}
print(s1, type(s1))
s2 = {10, 10}
print(s2, type(s2))  # 重复元素只会存在一个

s3 = set(range(5))
print(s3, type(s3))

s4 = set((1, 2, 3))
print(s4, type(s4))

s5 = set('python')
print(s5, type(s5))

{40, 10, 20, 30} <class ‘set’>
{10} <class ‘set’>
{0, 1, 2, 3, 4} <class ‘set’>
{1, 2, 3} <class ‘set’>
{‘h’, ‘o’, ‘n’, ‘p’, ‘y’, ‘t’} <class ‘set’>

7.2 操作

1、判断:innot in

s1 = {10, 20, 30, 40}
print(10 in s1)
print(10 not in s1)

True
False

2、新增

  • add():一次添加一个元素
  • update():一次至少添加一个元素
s1.add(50)
print(s1)
s1.update({80, 90}, [2, 3], ('num', 28), {'age': 18})
print(s1)

{40, 10, 50, 20, 30}
{2, 3, 40, ‘num’, 10, ‘age’, 80, 50, 20, 90, 28, 30}

3、删除

  • remove(value):一次删除一个指定元素,不存在则报错
  • discard(value):一次删除一个指定元素,不存在不报错
  • pop():一次删除一个随机元素
  • clear():清空集合
s1.remove('age')
print(s1)
# s1.remove(7)  # error
s1.discard(7)
print(s1)
s1.pop()
print(s1)
s1.clear()
print(s1)

{2, 3, ‘num’, 40, 10, 80, 50, 20, 90, 28, 30}
{2, 3, ‘num’, 40, 10, 80, 50, 20, 90, 28, 30}
{3, ‘num’, 40, 10, 80, 50, 20, 90, 28, 30}
set()

7.3 集合间的关系

  • 是否相等,可以使用运算符 ==!= 进行判断
  • 一个集合是否是另一个集合的子集,可以调用 issubset() 方法进行判断
  • 一个集合是否是另一个集合的超集,可以调用 issuperset() 方法进行判断
  • 两个集合是否没有交集,可以调用 isdisjoint() 方法进行判断
d1 = {10, 20}
d2 = {10, 20}
print(d1 == d2)

d3 = {10, 20, 30, 40}
print(d1 != d3)

print(d1.issubset(d3))
print(d3.issuperset(d1))

d4 = {30, 40}
print(d1.isdisjoint(d3))
print(d1.isdisjoint(d4))

True
True
True
True
False
True

7.4 数据操作

  • 交集:intersection()
  • 并集:union()
  • 差集:difference()
  • 对称差集:symmetric_difference()
d1 = {10, 20}
d2 = {20, 30, 40}

# 交集
print(d1.intersection(d2))
# 并集
print(d1.union(d2))
# 差集
print(d1.difference(d2))
print(d2.difference(d1))
# 对称差集
print(d1.symmetric_difference(d2))

{20}
{20, 40, 10, 30}
{10}
{40, 30}
{40, 10, 30}

7.4 集合生成式

s1 = {i * i for i in range(10)},和列表生成式类似,只是括号不同

  • i * i:表示列表元素的表达式
  • i:自定义变量
  • range(10):可迭代对象
s1 = {i * i for i in range(10)}
print(s1)

{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}

列表、字典、元组、集合总结

8. 字符串

在 Python 中字符串是基本数据类型,是一个不可变的字符序列

8.1 驻留机制

仅保存一份相同且不可变字符串或整数的方法,不同的值被存放在驻留池中,Python 的驻留机制对相同的字符串或整数只保留一份拷贝,后续创建相同字符串或整数时,不会开辟新空间,而是把该字符串的地址或整数赋给新创建的变量

驻留机制的几种情况,注意这里要使用 Python 的命令行进行测试结果才正确,使用 PyCharm 结果可能会出现偏差,因为 Pycharm 对字符串进行了优化处理

  • 字符串的长度为 0 或 1 时
  • 符合标识符的字符串
  • 字符串只在编译时进行驻留,而非运行时
  • [-5, 256] 之间的整数数字
  • sys 的 intern() 方法强制两个字符串指向同一个对象
>>> s1 = '%'
>>> s2 = '%'
>>> s1 is s2
True
>>> s3 = 'abc%'
>>> s4 = 'abc%'
>>> s3 is s4
False
>>> s3 == s4
True
>>> s5 = 'abcx'
>>> s6 = 'abcx'
>>> s5 is s6
True
>>> s7 = 'abc'
>>> s8 = 'ab' + 'c'
>>> s9 = ''.join(['ab', 'c'])
>>> s7 is s8
True
>>> s7 is s9
False
>>> s10 = -5
>>> s11 = -5
>>> s10 is s11
True
>>> s12 = -6
>>> s13 = -6
>>> s12 is s13
False
>>> type(s13)
<class 'int'>
>>> s3 is s4
False
>>> import sys
>>> s3 = sys.intern(s4)
>>> s3 is s4
True

优缺点:

  • 当需要值相同的字符串时,可以直接从驻留池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是比较影响性能的
  • 在需要进行字符串拼接时建议使用 str 类型的 join() 方法,而非 +,因为 join() 方法是先计算出所有字符的长度,然后再拷贝,只 new 一次对象,效率比 + 要高

8.2 操作

8.2.1 查询

  • index(sub):查找子串 subStr 第一次出现的位置,不存在则报错
  • rindex(sub):查找子串 subStr 最后一次出现的位置,不存在则报错
  • find(sub):查找子串 subStr 第一次出现的位置,不存在则返回 -1
  • rfind(sub):查找子串 subStr 最后一次出现的位置,不存在则返回 -1
s1 = 'hello,hello'
print(s1.index('lo'))
print(s1.rindex('lo'))
print(s1.find('lo'))
print(s1.rfind('lo'))

print(s1.find('xx'))
print(s1.index('xx'))  # error

3
9
3
9
-1

8.2.2 大小写转换

转换后会产生一个新的字符串对象

  • upper():将字符串中的所有字符都转成大写字母
  • lower():将字符串中的所有字符都转成小写字母
  • swapcase():将字符串中的所有大写字母转成小写字母,小写字母转成大写字母
  • capitalize():把第一个字符转成大写,其余字符转成小写
  • title():把每个单词的第一个字符转成大写,剩余字符转成小写
s1 = 'hello,WORLD'
print(s1.upper())
print(s1.lower())
print(s1.swapcase())
print(s1.capitalize())
print(s1.title())

HELLO,WORLD
hello,world
HELLO,world
Hello,world
Hello,World

8.2.3 内容对齐

  • center(width, fill):居中对齐,填充参数默认为空格,宽度小于等于原长度则返回原字符串
  • ljust(width, fil):左对齐,填充参数默认为空格,宽度小于等于原长度则返回原字符串
  • rjust(width, fil):右对齐,填充参数默认为空格,宽度小于等于原长度则返回原字符串
  • zfill(width):右对齐,填充参数为 0,宽度小于原长度则返回原字符串
s1 = 'hello'
print(s1.center(10, '*'))
print(s1.ljust(10, '*'))
print(s1.rjust(10, '*'))
print(s1.zfill(10))

hello*
hello*****
*****hello
00000hello

8.2.4 分割

返回值都是一个列表

  • split(sep, max):从左边开始分割,默认分割字符为空格,在分割次数达到 max 之后,剩下的子串会单独作为一部分
  • rsplit(sep, max):从右边开始分割,其他与上同
s1 = 'he+llo wor+ld pyth+on'
print(s1.split())
print(s1.split('+'))
print(s1.split('+', 2))

print(s1.rsplit())
print(s1.rsplit('+'))
print(s1.rsplit('+', 2))

[‘he+llo’, ‘wor+ld’, ‘pyth+on’]
[‘he’, ‘llo wor’, ‘ld pyth’, ‘on’]
[‘he’, ‘llo wor’, ‘ld pyth+on’]
[‘he+llo’, ‘wor+ld’, ‘pyth+on’]
[‘he’, ‘llo wor’, ‘ld pyth’, ‘on’]
[‘he+llo wor’, ‘ld pyth’, ‘on’]

8.2.5 判断字符串

  • isidentifier():判断指定的字符串是否是合法的标识符
  • isspace():判断指定的字符串是否全部由空白字符组成(回车、换行、空格、水平制表符)
  • isalpha():判断指定的字符串是否全部由字母组成
  • isdecimal():判断指定的字符串是否全部由十进制的数字组成
  • isnumeric():判断指定的字符串是否全部由数字组成
  • isalnum():判断指定的字符串是否全部由字母和数字组成
print('标识符')
s1 = 'python'
s2 = 'python%'
print(s1.isidentifier())
print(s2.isidentifier())

print('空白符')
s3 = '  '
print(s3.isspace())
print(s1.isspace())

print('字母')
print(s1.isalpha())
print(s2.isalpha())

print('十进制数字')
s4 = '123四'
s5 = '123'
print(s4.isdecimal())
print(s5.isdecimal())

print('数字')
print(s4.isnumeric())

print('字母和数字')
s6 = 'ab123四%'
s7 = 'ab123四'
print(s6.isalnum())
print(s7.isalnum())

标识符
True
False
空白符
True
False
字母
True
False
十进制数字
False
True
数字
True
字母和数字
False
True

8.2.6 替换与合并

  • replace(sub, replace, max):将某些子串替换为其他字符串,max 表示最大替换次数
  • join():将列表或元组合并成一个字符串
s1 = 'hello,world'
s2 = s1.replace('l', 'x')
print(s2)
s3 = s1.replace('l', 'x', 2)
print(s3)
print(s1)

s4 = ''.join(['hello', 'world'])
s5 = ''.join(('hello', 'world'))
print(s4)
print(s5)

hexxo,worxd
hexxo,world
hello,world
helloworld
helloworld

8.2.7 比较

使用运算符 >、<、>=、<=、==、!=

比较规则:依次比较每个字符,遇到不匹配的直接返回

比较原理:两个字符进行比较时,比较的是其 original value(原始值),调用内置函数 ord() 可以得到指定字符的 original value,与内置函数 ord() 对应的是内置函数 chr(),调用内置函数 chr() 指定 original value 可以得到对应的字符

s1 = 'apple'
s2 = 'app'

print(s1 > s2)
print(ord('a'))
print(chr(97))

True
97
a

8.2.8 切片

s1 = 'hello,world'

s2 = s1[4:]
print(s2)

s3 = s1[:5]
print(s3)

s4 = s1[2:12:2]
print(s4)

# 从后往前切片
s5 = s1[::-1]
print(s5)

s6 = s1[-6::1]
print(s6)

o,world
hello
lowrd
dlrow,olleh
,world

8.3 格式化

1、% 作为占位符

  • %s:字符串
  • %i%d:整数,可以实现宽度
  • %f:浮点数,可以实现精度
name = '张三'
age = 18
print('我叫%s, 今年%d岁' % (name, age))

print('%10i' % 99)
print('%.3f' % 3.1415926)

我叫张三, 今年18岁
99
3.142

2、{} 作为占位符,使用索引来表示占位,配合 format() 方法来使用

print('我叫{0}, 今年{1}岁, {0}'.format(name, age))
print('{0}'.format(3.1415926))
print('{0:.3}'.format(3.1415926))  # 3 位数
print('{0:.3f}'.format(3.1415926))  # 3 位小数
print('{:.3f}'.format(3.1415926))
print('{:10.3f}'.format(3.1415926))

我叫张三, 今年18岁, 张三
3.1415926
3.14
3.142
3.142
3.142

3、前面加上 f 来表示格式化,占位符使用 {var}

print(f'我叫{name}, 今年{age}岁')

我叫张三, 今年18岁

8.4 编码与解码

  • 编码:将字符串转换为二进制数据(bytes)
  • 解码:将 bytes 类型数据转换成字符串类型

计算机 A(str 在内存中以 Unicode 表示) --> encode(str) --> byte 字节传输 --> decode --> 计算机 B

s1 = '你好'
b1 = s1.encode('GBK')
print(b1)  # 一个中文占两个字节
b2 = s1.encode('UTF-8')
print(b2)  # 一个中文占三个字节

# 解码格式要和编码格式相同
print(b1.decode(encoding='GBK'))
print(b2.decode(encoding='UTF-8'))

b’\xc4\xe3\xba\xc3’
b’\xe4\xbd\xa0\xe5\xa5\xbd’
你好
你好

9. 函数

函数就是执行特定任务和完成特定功能的一段代码

优点:

  • 复用代码
  • 隐藏实现细节
  • 提高可维护性
  • 提高可读性便于调试

9.1 定义与调用

def f1(a, b):
    return a + b


result1 = f1(3, 4)
print(result1)
result1 = f1(b=4, a=3)
print(result1)

7
7

9.2 参数

9.2.1 参数传递

1、实参

实际参数的值,一般是函数的调用处,如上面的 result1 = f1(3, 4)result1 = f1(b=4, a=3)

  • 位置传参,根据参数的顺序一一对应,如 result1 = f1(3, 4)
  • 关键字传参,根据参数名称传递,如 result = f1(b=4, a=3)

2、形参

形式参数,一般是函数的定义处,如上面的 def f1(a, b)

9.2.2 默认值

函数定义时可以给参数设置默认值,调用函数时未传则使用默认值,传了则使用传递的值

def fun1(a, b=10):
    print(a, b)


fun1(10)
fun1(10, 30)

10 10
10 30

9.2.3 可变参数

1、位置传参

使用 * 定义可变的位置形参,结果为一个元组

def fun2(*args):
    print(args, type(args))


fun2(2)
fun2(2, 3, 4, 5)

2、关键字传参

使用 ** 定义可变的关键词形参,结果为一个字典

(2,) <class ‘tuple’>
(2, 3, 4, 5) <class ‘tuple’>

def fun3(**kwargs):
    print(kwargs, type(kwargs))


fun3(a=10)
fun3(a=20, b=30, c=40)

{‘a’: 10} <class ‘dict’>
{‘a’: 20, ‘b’: 30, ‘c’: 40} <class ‘dict’>

注意:相同类型的可变参数只能存在一个,同时存在可变的位置形参和可变的关键词形参时,位置形参要在前面

def fun4(*args, **kwargs):
    pass

9.3 返回值

  • 没有返回值,可以省略 return
  • 返回值为 1 个时,直接返回原值
  • 返回多个值时,返回结果为元组
def f1(num):
    odd = []
    even = []
    for i in num:
        if i % 2:
            odd.append(i)
        else:
            even.append(i)
    return odd, even


result1 = f1([1, 3, 2, 3, 4, 5])
print(result1, type(result1))


def f2(num):
    return num


result2 = f2(123)
print(result2, type(result2))
result3 = f2('123')
print(result3, type(result3))

([1, 3, 3, 5], [2, 4]) <class ‘tuple’>
123 <class ‘int’>
123 <class ‘str’>

9.4 变量的作用域

即程序代码能访问该变量的区域

  • 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用 global 声明,这个变量就会成为全局变量
  • 全局变量:函数体外定义的变量,可作用于函数内外
a = 10


def fun1():
    b = 10
    global c
    c = 20
    print(a, b, c)


fun1()
print(a)
print(b)  # error
print(c)

10 10 20
10
20

9.5 递归函数

即在一个函数内部调用该函数本身,需要递归调用和递归终止条件。每递归调用一次函数,都会在栈内存分配一个栈帧,每执行完一次函数,都会释放对应的空间

  • 缺点:占用内存多,效率低下
  • 优点:思路和代码简单
def fun1(num):
    if 1 == num:
        return 1
    else:
        return num * fun1(num - 1)


print(fun1(5))

120

10. 异常

10.1 异常处理

  • try...except:如果 try 块中抛出异常,则执行 except 块
  • try...except...else:如果 try 块中抛出异常,则执行 except 块,否则执行 else 块
  • try...except...else...finally:finally 块无论是否发生异常都会执行,常用来释放 try 块中申请的资源
try:
    i = 1 / 0
    print(i)
except Exception as e:
    print('出错了')
    print(e)

try:
    i = 1 / 1
    print(i)
except Exception as e:
    print('出错了')
    print(e)
else:
    print('正常运行')

try:
    i = 1 / 0
    print(i)
except Exception as e:
    print('出错了')
    print(e)
else:
    print('正常运行')
finally:
    print('最后执行')

try:
    i = 1 / 1
    print(i)
except Exception as e:
    print('出错了')
    print(e)
else:
    print('正常运行')
finally:
    print('最后执行')

出错了
division by zero
1.0
正常运行
出错了
division by zero
最后执行
1.0
正常运行
最后执行

10.2 常见异常类型

序号异常类型描述
1ZeroDivisionError除(或取模)零(所有数据类型)
2IndexError序列中没有此索引(index)
3KeyError映射中没有这个键
4NameError未声明/初始化对象(没有属性)
5SyntaxErrorPython 语法错误
6ValueError传入无效的参数
print(1 / 0)

l1 = [11, 22, 33]
print(l1[4])

d1 = {'name': '张三', 'age': 22}
print(d1['sex'])

print(num)

int a = 20

a = int('hello')

10.3 traceback 模块

使用 traceback 模块打印异常信息

import traceback

try:
    print('1.-----------')
    num = 10 / 0
except ZeroDivisionError as e:
    traceback.print_exc()

11. 类与对象

类,是多个类似事物组成的群体的统称,能够帮助我们快速理解和判断事物的性质

  • 数据类型
    • 不同的数据类型属于不同的类
    • 使用内置函数查看数据类型,type(100)
  • 对象
    • 不管是 100,还是 99、520 等,都是 int 类之下包含的相似的不同个例,这个个例专业术语称为实例或对象

Python 中一切皆对象

11.1 面向过程与面向对象

  • 面向过程:事物比较简单,可以用线性的思维去解决
  • 面向对象:事物比较复杂,使用简单的线性思维无法解决

共同点:都是解决实际问题的一种思维方式

二者相辅相成,并不是对立的,解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系,方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理

11.2 类的定义与组成

使用 class 修饰

class Student:
    pass


print(id(Student))
print(type(Student))
print(Student)

2443536301376
<class ‘type’>
<class ‘main.Student’>

类的组成

  • 类属性
  • 实例方法:普通方法
  • 静态方法: @staticmethod 修饰
  • 类方法:@classmethod 修饰
class Student:
    address = '吉林'  # 类属性

    def __init__(self, name, age):  # 构造函数
        self.name = name
        self.age = age

    def eat(self):  # 实例方法
        print('吃东西')

    @staticmethod
    def method():  # 静态方法
        print('静态方法')

    @classmethod
    def cm(cls):  # 类方法
        print('类方法')

11.3 对象的创建与调用

对象的创建又称为类的实例化,有了实例,就可以调用类中的内容

stu1 = Student('张三', 18)
print(id(stu1))
print(type(stu1))
print(stu1)

1693665418768
<class ‘main.Student’>
<main.Student object at 0x0000018A56535E10>

stu1.eat()
Student.eat(stu1)

stu1.method()
Student.method()

stu1.cm()
Student.cm()

print(stu1.name, stu1.age)
print(stu1.address)
print(Student.address)

吃东西
吃东西
静态方法
静态方法
类方法
类方法
张三 18
吉林
吉林

11.4 动态绑定属性和方法

stu1 = Student('张三', 18)
stu1.gender = '女'
print(stu1.name, stu1.age, stu1.gender)


def show():
    print('show')


stu1.show = show
stu1.show()

张三 18 女
show

11.5 面向对象的三大特征

  • 封装:提高程序的安全性
    • 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度
    • 在 Python 中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前面使用两个 _
  • 继承:提高代码的复用性
  • 多态:提高程序的可扩展性和可维护性

11.5.1 封装

上面提到如果不希望属性在类对象外部被访问,前面使用两个 _,但实际上还是可以通过 _类名___属性 来进行访问

class Student:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    def show(self):
        print(self.age)


stu1 = Student('张三', 20)
print(stu1.name)
print(stu1.__age)  # error
print(dir(stu1))
print(stu1._Student__age)

张三
[‘_Student__age’, ‘class’, ‘delattr’, ‘dict’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getstate’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘le’, ‘lt’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘name’, ‘show’]
20

11.5.2 继承

  • 如果一个类没有继承任何类,则默认继承 object
  • Python 支持多继承
  • 定义子类时,必须在其构造函数中调用父类的构造函数
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

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


class Student(Person):
    def __init__(self, name, age, stuNo):
        super().__init__(name, age)
        self.stuNo = stuNo


stu = Student('张三', 19, 10001)
stu.info()
print(stu.stuNo)

张三 19
10001

方法重写

class Student(Person):
    def __init__(self, name, age, stuNo):
        super().__init__(name, age)
        self.stuNo = stuNo

    def info(self):
        super().info()
        print(self.stuNo)


stu = Student('张三', 19, 10001)
stu.info()

张三 19
10001

多继承

class A:
    pass


class B:
    pass


class C(A, B):
    pass

object 类

object 类是所有类的父类,因此所有类都有 object 类的属性和方法

  • dir():内置函数,可以查看指定对象的所有属性
  • __str__():用于返回一个对于对象的描述,对应于内置函数 str() 经常用于 print() 方法,我们查看对象的信息,经常会对 __str__() 方法进行重写
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return '我的名字是{0}, 今年{1} 岁'.format(self.name, self.age)


stu = Student('张三', 19)
print(dir(stu))

print(stu)

[‘class’, ‘delattr’, ‘dict’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getstate’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘le’, ‘lt’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘age’, ‘name’]
我的名字是张三, 今年19 岁

11.5.3 多态(静态语言和动态语言)

简单来说,多态就是具有多种形态。它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法

  • 静态语言(如 Java),实现多态需要三个必要条件
    • 继承
    • 方法重写
    • 父类引用指向子类对象
  • 动态语言(如 Python),动态语言的多态崇尚“鸭子类型”
    • 当看到一只鸟走起来像鸭子,游泳起来像鸭子,那么这只鸟就可以被称之为鸭子
    • 在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为
class Animal:
    def eat(self):
        print('动物')


class Dog(Animal):
    def eat(self):
        print('狗')


class Cat(Animal):
    def eat(self):
        print('猫')


class Person:
    def eat(self):
        print('人')


def fun(obj):
    obj.eat()


fun(Cat())
fun(Dog())
fun(Person())



11.6 特殊属性

  • __dict__:获得类对象或实例对象所绑定的所有属性和方法的字典
  • __class__:获取对象所属的类
  • __bases__:获取父类类型的元组
  • __mro__:获取类的层次结构
  • __subclasses__:获取子类类型的列表
class A:
    pass


class B:
    pass


class C(A, B):
    def __init__(self, name):
        self.name = name


c = C('张三')
print(c.__dict__)
print(C.__dict__)
print(c.__class__)
print(C.__bases__)
print(C.__mro__)
print(A.__subclasses__())

{‘name’: ‘张三’}
{‘module’: ‘main’, ‘init’: <function C.init at 0x0000023C55F68CC0>, ‘doc’: None}
<class ‘main.C’>
(<class ‘main.A’>, <class ‘main.B’>)
(<class ‘main.C’>, <class ‘main.A’>, <class ‘main.B’>, <class ‘object’>)
[<class ‘main.C’>]

11.7 特殊方法

  • __len__():通过重写 __len__() 方法,让内置函数 len() 的参数可以是自定义类型
  • __add__():通过重写 __add__() 方法,可以让自定义对象具有 “+”功能
  • __new__():用于创建对象
  • __init__():对创建的对象进行初始化
class Student:
    def __init__(self, name):
        self.name = name

    def __len__(self):
        return len(self.name)

    def __add__(self, other):
        return self.name + other.name


stu1 = Student('张三')
stu2 = Student('李四')
print(len(stu1))
print(len(stu2))

print(stu1.__add__(stu2))

2
2
张三李四

创建对象过程

先执行 new() 方法创建对象,然后将创建的对象返回,该对象即为 self,也就是实例对象,然后再执行 init() 方法

class Student:
    def __init__(self, name, age):
        print('init 创建的对象自身id', id(self))
        self.name = name
        self.age = age

    def __new__(cls, *args, **kwargs):
        print('new Student类', cls, id(cls))
        obj = super().__new__(cls)
        print('创建的对象id', id(obj))
        return obj


stu1 = Student('张安', 19)
print('Student类id', id(Student))
print('stu1对象id', id(stu1))

new Student类 <class ‘main.Student’> 1978364975584
创建的对象id 1978363977808
init 创建的对象自身id 1978363977808
Student类id 1978364975584
stu1对象id 1978363977808

11.8 类的赋值与拷贝

1、变量的赋值操作

只是形成两个变量,实际上还是指向同一个对象

class Cpu:
    pass


cpu1 = Cpu()
cpu2 = cpu1
print(cpu1)
print(cpu2)

<main.Cpu object at 0x000002E31C210B50>
<main.Cpu object at 0x000002E31C210B50>

2、浅拷贝

Python 拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象

class Cpu:
    pass


class Disk:
    pass


class Computer:
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk


disk = Disk()
computer1 = Computer(cpu1, disk)

import copy

computer2 = copy.copy(computer1)
print(computer1, computer1.cpu, computer1.disk)
print(computer2, computer2.cpu, computer2.disk)

<main.Computer object at 0x000002016406A290> <main.Cpu object at 0x000002016406A210> <main.Disk object at 0x000002016406A250>
<main.Computer object at 0x000002016406A350> <main.Cpu object at 0x000002016406A210> <main.Disk object at 0x000002016406A250>

3、深拷贝

使用 copy 模块的 deepcopy() 函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同

computer3 = copy.deepcopy(computer1)
print(computer1, computer1.cpu, computer1.disk)
print(computer3, computer3.cpu, computer3.disk)

<main.Computer object at 0x000002D3219EA310> <main.Cpu object at 0x000002D3219EA290> <main.Disk object at 0x000002D3219EA2D0>
<main.Computer object at 0x000002D3219EA350> <main.Cpu object at 0x000002D3219EA410> <main.Disk object at 0x000002D3219EA490>

12. 模块

模块,英文为 Module,在 Python 中一个扩展名为 .py 的文件就是一个模块

优点:

  • 方便其他程序和脚本的导入并使用
  • 避免函数名和变量名冲突
  • 提高代码的可维护性
  • 提高代码的可复用性

12.1 模块的引入

1、全部引入

basic.py 文件

def fun():
    print('basic fun')


class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

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

在另一个文件中引入

import basic

basic.fun()
stu1 = basic.Student('张三', 18)
stu1.info()

# import basic as bas
# 
# bas.fun()
# stu1 = bas.Student('张三', 18)
# stu1.info()

basic fun
张三 18

2、部分引入

from basic import fun

fun()
stu1 = basic.Student('张三', 18)  # error
stu1.info()

basic fun

12.2 以主程序形式运行

在每个模块的定义中都包括一个记录模块名称的变量 __name__,程序可以检查该变量,以确定他们在哪个模块中执行,如果一个模块不是被导入到其他程序中执行,那么它可能在解释器的顶级模块中执行,顶级模块的 __name__ 变量的值为 __main__

add.py 文件

def add(num1, num2):
    return num1 + num2


print(add(10, 20))

另一个文件中引入

import add

print(add.add(100, 200))

30
300

此时会输出 30、300,而这里的 30 是 add.py 文件输出的,此时我们运行的是另一个文件,add.py 文件只是作为引入其 add() 函数,不应该执行其他代码,因此加上判断,修改如下

def add(num1, num2):
    return num1 + num2


if __name__ == '__main__':
    print(add(10, 20))

此时输出只为 300

12.3 包

Python 中的包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录

作用:

  • 代码规范
  • 避免模块名称冲突

包和目录的区别:

  • 包含 __init__.py 文件的目录称为包
  • 目录里通常不包含 __init__.py 文件

如包结构如下

其他文件引入

import package.add as add

print(add.a)

# from package import add
#
# print(add.a)
#
# from package.add import a
#
# print(a)

10

12.4 Python 中常用的内置模块

模块名描述
sys与 Python 解释器及其环境操作相关的标准库
time提供与时间相关的各种函数的标准库
os提供了访问操作系统服务功能的标准库
calendar提供与日期相关的各种函数的标准库
urllib用于读取来自网上(服务器)的数据标准库
json用于使用 JSON 序列化和反序列化对象
re用于在字符串中执行正则表达式匹配和替换
math提供标准算术运算函数的标准库
decimal用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging提供了灵活的记录事件、错误、警告和调试信息等日志信息的功能
import sys

print(sys.getsizeof('张三'))
print(sys.getsizeof(20))
print(sys.getsizeof(False))
print(sys.getsizeof(2011.233332))
print(sys.getsizeof([11, 22, 33, 44, 77]))

import time

print(time.time())
print(time.localtime())
print(time.localtime(time.time()))

import urllib.request

print(urllib.request.urlopen('http://www.baidu.com').read())

import math

print(math.pi)

78
28
28
24
104
1690177727.869666
time.struct_time(tm_year=2023, tm_mon=7, tm_mday=24, tm_hour=13, tm_min=48, tm_sec=47, tm_wday=0, tm_yday=205, tm_isdst=0)
time.struct_time(tm_year=2023, tm_mon=7, tm_mday=24, tm_hour=13, tm_min=48, tm_sec=47, tm_wday=0, tm_yday=205, tm_isdst=0)
3.141592653589793

12.5 第三方模块的安装及使用

1、安装

pip install schedule,schedule 为一个任务调度模块

2、使用

import schedule
import time


def job():
    print('hello')


schedule.every(3).seconds.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)

hello
hello
hello

13. 文件

13.1 编码格式

Python 解释器使用的是 Unicode(内存),.py 文件在磁盘上使用 UTF-8 存储(外存)

# coding:utf-8:指定文件格式

13.2 文件读写

文件的读写俗称 “IO 操作”,首先 .py 文件在解释器上运行,当涉及到读写文件等操作系统的资源时,解释器会调用 OS,即操作系统,然后 OS 再去操作磁盘

内置函数 open() 创建文件对象,file = open(filename, mode, buffering, encoding)

  • file:被创建的文件对象
  • open():创建文件对象的函数
  • filename:要创建或打开的文件名称
  • mode:打开模式,默认为只读
  • buffering:值为 0,则表示不会有寄存,值为 1,访问文件时会寄存行;值大于 1,表明这就是寄存区的缓冲大小;如果取负值,寄存区的缓冲大小则为系统默认
  • encoding:文本文件中字符的编码格式,默认为 GBK

a.txt 文件,编码为 UTF-8

你好
Python

对应读取文件也要设置编码格式为 UTF-8

# file = open('a.txt', 'r', 1, 'UTF-8')
file = open('a.txt', encoding='UTF-8')
print(file.readlines())
file.close()

[‘你好\n’, ‘Python’]

13.2.1 常用的文件打开模式

按文件中数据的组织形式,文件分为以下两大类

  • 文本文件:存储的是普通“字符”文本,默认为 Unicode 字符集,可以使用记事本程序打开
  • 二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件打开,如 MP3 音频文件、JPG 图片、doc 文档等
打开模式描述
r以只读模式打开文件,文件的指针将会放在文件的开头
w以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头;如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾
b以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,如 rb、wb
+以读写方式打开文件,不能单独使用,需要与其他模式一起使用,如 a+

追加内容

file = open('a.txt', 'a', encoding='UTF-8')
file.write('你好')
file.close()

此时 a.txt 文件内容为

你好
Python你好

13.2.2 文件对象常用方法

方法名称与对应参数名称说明
read([size])从文件中读取 size 个字节或字符的内容返回,若省略 [size],则读取到文件末尾,即一次性读取文件所有内容
readline()从文本文件中读取一行内容
readlines()把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
wirte(str)将字符串 str 内容写入文件
writelines(s_list)将字符串列表 s_list 写入文本文件,不添加换行符
seek(offset, whence)把文件指针移动到新的位置,offset 表示相对于 whence 的位置,为正表示从结束方向移动,为负表示从开始方向移动;whence 为 0 表示从文件头开始计算(默认值),为 1 表示从当前位置开始计算,为 2 表示从文件尾开始计算
tell()返回文件指针的当前位置
flush()把缓冲区的内容写入文件,但不关闭文件
close()把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源

以读写模式打开文件,这里的 r 决定了文件指针的初始位置

file = open('a.txt', 'r+', encoding='UTF-8')
print(file.read(1))
file.seek(0)
print(file.readline())
file.seek(0)
print(file.readlines())

file.write('world')
file.seek(0)
print(file.readlines())
file.close()
你
你好

['你好\n', 'Python你好']
['你好\n', 'Python你好world']

13.3 os、os.path 模块的常用函数

os 模块是 Python 内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样

import os

os.system('notepad.exe')  # 打开记事本
os.system('calc.exe')  # 打开计算器

os 模块与 os.path 模块用于对目录或文件进行操作

os 模块函数说明
getcwd()返回当前的工作目录
listdir(path)返回指定路径下的文件和目录信息
mkdir(path, mode)创建目录
makedirs(path1/path2..., mode)创建多级目录
rmdir(path)删除目录
removedirs(path1/path2)删除多级目录
chdir(path)将 path 设为当前工作目录
walk()递归获取目录路径,名称及其子文件
os.path 模块函数说明
abspath(path)用于获取文件或目录的绝对路径
exists(path)用于判断文件或目录是否存在,如果存在返回 True,否则返回 False
join(path, name)将目录与目录或文件名拼接起来
splitext()分离文件名和扩展名
basename(path)从一个目录中提取文件名
dirname(path)从一个路径中提取文件路径,不包括文件名
isdir(path)用于判断是否为路径
import os
import os.path as path

# os.system('notepad.exe')  # 打开记事本
# os.system('calc.exe')  # 打开计算器

print(os.getcwd())

l1 = os.listdir('../file')
print(l1)

print(path.abspath('system.py'))
print(path.exists('D:\\DevelopTools\\Project\\fan-leaning-python\\fan\\file\\system.py'))
print(path.splitext('system.py'))
print(path.basename('D:\\DevelopTools\\Project\\fan-leaning-python\\fan\\file\\system.py'))
print(path.dirname('.D:\\DevelopTools\\Project\\fan-leaning-python\\fan\\file\\system.py'))
print(path.isdir('D:\\DevelopTools\\Project\\fan-leaning-python\\fan\\file\\system.py'))
print(path.isdir('D:\\DevelopTools\\Project\\fan-leaning-python\\fan\\file'))

D:\DevelopTools\Project\fan-leaning-python\fan\file
[‘a.txt’, ‘open.py’, ‘system.py’, ‘write.py’]
D:\DevelopTools\Project\fan-leaning-python\fan\file\system.py
True
(‘system’, ‘.py’)
system.py
.D:\DevelopTools\Project\fan-leaning-python\fan\file
False
True

import os

files = os.walk(os.getcwd())
for dirpath, dirname, filename in files:
    print(dirpath)
    print(dirname)
    print(filename)

D:\DevelopTools\Project\fan-leaning-python\fan\file
[‘walk’]
[‘a.txt’, ‘open.py’, ‘system.py’, ‘walk.py’, ‘write.py’]
D:\DevelopTools\Project\fan-leaning-python\fan\file\walk
[]
[‘walk.py’]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/792525.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++-stack 和 queue

stack 和 queue介绍 两者分别是C当中的 栈和队列&#xff0c;只不过在C当中&#xff0c;这两者没有用传统的方式&#xff0c;比如顺序存储和链式存储来实现了&#xff0c;两者现在使用的是一种权限的方式来实现&#xff1b; 都是用容器适配器来实现&#xff0c;开发者考虑到&a…

PyToch 深度学习 || 3. 卷积神经网络 | 3.1 深度学习中的卷积操作

深度学习中的卷积操作 文章目录 深度学习中的卷积操作1. 卷积2. 一维卷积2.1 使用nn.functional库中conv1d2.2 使用nn库中的Conv1d 3. 二维卷积3.1 nn.functional.conv2d3.2 nn.Conv2d 1. 卷积 加权求和是一种非常重要的运算&#xff0c;可以整合局部数字特征进而是提取局部信…

Linux CentOS监控系统的运行情况工具 - top/htop/glances/sar/nmon

在CentOS系统中&#xff0c;您可以使用以下工具来监控系统的运行情况&#xff1a; 1. top&#xff1a; top 是一个命令行工具&#xff0c;用于实时监控系统的进程、CPU、内存和负载情况。您可以使用以下命令来启动 top&#xff1a; top 输出 2. htop&#xff1a; htop 是一…

WSL 2 环境配置

WSL 2 环境配置 wsl2是windows内置的linux子系统&#xff0c;安装步骤如下&#xff1a; Win10 版本号为 2004&#xff08;内部版本19041或更高&#xff09;即可&#xff0c;如果低于此版本可使用 Windows 10 易升工具手动升级。下载 Windows 10 易升工具&#xff1a; https:…

DAY52:动态规划(十七)子序列问题:最长递增子序列+最长连续递增序列+最长重复子数组

文章目录 300.最长递增子序列&#xff08;注意初始化和结果取值&#xff09;思路DP数组含义递推公式初始化最开始的写法debug测试&#xff1a;解答错误debug测试2&#xff1a;result初始值 修改完整版总结 674.最长连续递增序列思路1&#xff1a;滑动窗口思路2&#xff1a;动态…

【Leetcode】54.螺旋矩阵

一、题目 1、题目描述 给你一个 m m m 行 n n n 列的矩阵 matrix,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例1: 输入:matrix =

安防监控视频汇聚EasyCVR修改录像计划等待时间较长,是什么原因?

安防监控视频EasyCVR视频融合汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、云存储、回放与检…

项目——负载均衡在线OJ

目录 项目介绍开发环境所用技术项目宏观结构编写思路1. 编写compile_server1.1 编译模块编写1.2 运行功能1.3compile_runner 编译与运行1.4 编写compile_server.cpp调用compile_run模块&#xff0c;形成网络服务 2. 编写基于MVC的oj_server2.1 oj_server.cpp的编写2.2 oj_model…

Unity进阶--对象池数据场景管理器笔记

文章目录 泛型单例类泛型单例类&#xff08;不带组件版&#xff09;对象池管理器数据管理器场景管理器 泛型单例类 using System.Collections; using System.Collections.Generic;public abstract class ManagersSingle<T> where T : new() {private static T instance;…

OSCP 学习:Kali Linux 基本命令

Bash 环境 环境变量 当我们开启新的bash时候&#xff0c;它会拥有自己的环境变量 我是这样理解 环境变量的&#xff1a; 每个程序都有自己运行的地址 我们用一个变量来储存它的地址 这个变量就叫环境变量 Kali 最常用的环境变量 就是 $PATH。这个我们可以用这个变量进行不正当…

selenium浏览器驱动下载

Chrome谷歌浏览器 下载地址&#xff1a;http://chromedriver.storage.googleapis.com/index.html 不同的Chrome的版本对应的chromedriver.exe 版本也不一样&#xff0c;下载时不要搞错了。 如果是最新的Chrome, 下载最新的chromedriver.exe 就可以了。 Firefox火狐浏览器 驱…

B073-封装工具类 服务模块(后台)

目录 拿当前登录人信息工具类服务模块业务分析表结构后端代码后台代码覆写删除-加详情一起删调整前端Data&#xff0c;handleAdd和编辑框覆写新增编辑按钮展示详情资源&#xff1a;多图上传和回显图片 拿当前登录人信息工具类 工具类准备&#xff1a;LoginContext: 登录上下文…

前端性能测试

目录 前言&#xff1a; 前端性能 1、优化 2、Lighthouse 使用 4、Lighthouse 报告参数的标准 5、更多产品 前言&#xff1a; 前端性能测试是一个广泛的领域&#xff0c;它旨在评估前端应用程序的性能和可靠性。前端性能测试需要使用各种测试工具和技术&#xff0c;包括浏…

功率信号源的基本工作原理、用途和应用方法

功率信号源是一种可以产生恒定或可变功率输出的测试设备。在电子实验中&#xff0c;功率信号源广泛应用于各种不同的应用&#xff0c;下面安泰电子就来介绍功率信号源的基本工作原理、用途和应用方法。 功率信号源的基本工作原理 功率信号源的基本工作原理是将电能转换成信号能…

【前端实习评审】对小说详情模块的产品原型有一定的自己理解

大家好&#xff0c;本篇文章分享一下【校招VIP】免费商业项目“推推”第一期书籍详情模块前端同学的文档作品。该同学来自中国科学院大学计算机技术专业。 本项目亮点难点&#xff1a;1 热门书籍在更新点的访问压力 2 书籍更新通知的及时性和有效性 3 书荒:同好推荐的可能性 4…

血压诊断米家智能血压计方案

智能血压计产品介绍: 智能血压计是一种基于蓝牙技术的便携式血压测量设备。它通过无线连接与智能手机或其他设备同步并联接到APP端&#xff08;米家&#xff09;&#xff0c;可以准确测量用户的血压数据&#xff0c;并通过手机应用程序进行记录和分析。 智能血压计产品结构: 智…

Win10的两个实用技巧系列之蓝屏代码大全及解决方案、更改应用优先级的技巧

Win10怎么设置程序优先级? Win10更改应用优先级的技巧 Win10怎么设置程序优先级&#xff1f;Win10系统中任务管理器想要设置优先级&#xff0c;该怎么设置呢&#xff1f;下面我们就来看看Win10更改应用优先级的技巧 有些Win10用户想要调整程序优先级&#xff0c;以确保某些…

Sentinel限流中间件

目录 介绍 Sentinel 的特征 Sentinel 的组成 实战使用 简单实例 配置本地控制台 使用可视化ui配置简单流控 配置异步任务限流 使用注解定义限流资源 SpringCloud整合Sentinel 简单整合 并发线程流控 关联模式 整合openFeign使用 介绍 随着微服务的流行&#xff0…

iOS私钥证书和证书profile文件的生成攻略

在使用uniapp打包ios app的时候&#xff0c;要求我们提供一个私钥证书和一个证书profile文件&#xff0c;私钥证书可以使用mac电脑的钥匙串访问程序来生成&#xff0c;也可以使用香蕉云编来生成。证书profile文件可以直接在苹果开发者中心生成。 有部分刚接触ios开发的同学们&…

Easy-Es笔记

一、Easy-ES概述 Easy-Es&#xff08;简称EE&#xff09;是一款ElasticSearch-ORM框架&#xff0c;在原生 RestHighLevelClient 的基础上&#xff0c;只做增强不做改变&#xff0c;为简化开发、提高效率而生。Easy-Es采用和MP一致的语法设计&#xff0c;能够显著降低ElasticSea…