跳至主要內容

basic knowledge extension for Python

Ryan原创...大约 31 分钟pythonpython编程教程

basic knowledge extension for Python

引言: 这篇文章旨在为 Ryan 本人服务

1. 基本语法元素

1.1 格式化输出

format的格式
  1. 填充输出
# 右对齐
a = 123
print('{0:_>4}'.format(a)) # _123
b = 1111
print('{0:&>10}'.format(b)) # &&&&&&1111
# 左对齐
a = 'a'
print('{0:*<5}'.format(a)) # a****
# 居中
a = 'middle'
print('{0:#^16}'.format(a)) # #####middle#####
print('{0:#^15}'.format(a)) # ####middle#####
print('{0:#^17}'.format(a)) # #####middle######
  1. 数字千分位分隔符
# 显示1,000,000
a = 1000000
print("{0:,}".format(a)) # 1,000,000

# 填充优先级高于千分位
a = 1000000
print("{0:*>20,}".format(a)) # ***********1,000,000
  1. 浮点数简化输出
  • 留两位小数
a = 3.1415926
print("{0:.2f}".format(a)) # 3.14
  • 按百分数输出
a = 3.1415926
print("{0:%}".format(a)) # 314.159260%


a = 3.1415926
print("{0:.1%}".format(a)) # 314.2%
  • 科学计数法输出
a = 0.1415926
print("{0:e}".format(a)) # 1.415926e-01


a = 0.0000926
print("{0:.2e}".format(a)) # 9.26e-05
  1. 整数的进制转换输出
  • 十进制整数转二进制、unicode码、十进制、八进制、十六进制输出
print('二进制{0:b}, Unicode码{0:c}, 十进制{0:d}, 八进制{0:o}, 十六进制{0:x}'.format(450))

# output: 二进制111000010, Unicode码ǂ, 十进制450, 八进制702, 十六进制1c2 

1.2 程序格式

1. 最大行长度

所有行限制的最大字符数为 79

2. 缩进

  • 用缩进来表示语句间的逻辑
  • 在 for while if def class等:之后下一行开始进行缩进,表明后续代码与前句之间的从属关系
  • 缩进量:4字符

3.使用空格

  • 二元运算符两边加一个加空格
x = 2
x += 4
6 > 2
  • 使用不同优先级的运算符,考虑在最低优先级的运算符周围添加空格
x = x*2 - 1
z = x*2 + y*y
c = (a+b) * (a-b)
  • 在逗号后使用空格
x, y = 1, 2
ls = [1, 2, 3]
  • 不要使用一个以上的空格
x =             2

4. 避免使用空格

  • 在指定关键字参数或者默认参数值的时候,不要在 = 附近加上空格
def fun(n=1, m=2):
    pritn(n, m)

小结:

  1. 以上属于PEP8格式指南的部分内容,养成良好的编码规范利人利己
  2. 格式约定的目的:
    1. 使大量Python代码风格一致
    2. 提升代码可读性
  3. 尽信书不如无书,不应死板教条的执行格式规范
    1. 项目规范优先

2. 基本数据类型

2.1 数字型

2.1.1. 整数————不同进制的转换

默认输入:十进制

二进制:0b

八进制:0o

十六进制:0x

16 == 0b10000 == 0o20 == 0x10
  • 十进制与其他进制的转换
a = bin(16) # 2
b = oct(16) # 8
c = hex(16) # 16
print(a, b, c)

# output
0b10000 0o20 0x10

注意

转换后的结果会变为字符串(str)类型

print(type(a), type(b), type(c))

# output
<class 'str'> <class 'str'> <class 'str'>
  • 其他进制转换为十进制
a = bin(16)
b = oct(16)
c = hex(16)

d = int(a, 2) # 二进制转十进制
e = int(b, 8) # 八进制转十进制
f = int(c, 16) # 十六进制转十进制
print(d, e, f) 

# output
16 16 16

2.1.2. 浮点数

      • 不确定小数问题**
print((0.1 + 0.2) == 0.3) # False
print(0.1 + 0.2) # 0.30000000000000004
  • 产生该问题的原因:

浮点数小数部分在计算机是由二进制表示的,二进制小数不能表示所有的十进制小数

二进制和十进制实际数值
  • 通常情况下不会影响精度
print(0.1 + 0.7) # 0.7999999999999999
  • 如何求得真正想表达的十进制:————四舍五入(.round())
a = 3 * 0.1
b = round(a, 1)
print(a) # 0.30000000000000004
print(b) # 0.3
print(b == 0.3) # True

2.1.3. *虚数

  • 格式:a + bja + bJ
a = 3 + 4j
b = 2 + 5J
print(a, b)

# output
(3+4j) (2+5j)

注意

若虚部数值为 1, 也要写成 1j

a = 1 + j
print(a)

# output
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\Coder\Python\basic_knowledge_extension\Data_type\imaginary_number.py", line 8, in <module>
    a = 1 + j
NameError: name 'j' is not defined

2.1.4. 数字型的函数

  • 绝对值 abs()
print(abs(-1)) # 1
print(abs(3+4j))  # 对复数a+bj 执行的是求模运算(a^2+b^2)^0.5
  • 幂次方 pow()
print(pow(2, 5)) # 32
print(pow(2, 5, 3)) # 等价于 (2^5) % 3 = 2
  • 四舍五入 round
a = 1.618
print(round(a)) # 默认状态下四舍五入保留零位小数

print(round(a, 2)) # 保留两位小数

print(round(a, 10)) # 位数不足时, 无需不起!!!!!!

# output
2
1.62
1.618
  • 整除返回商和模 divmod()
a, b = divmod(11,3)
print(a) # 整除数
print(b) # 余数

# output
3
2
  • 最大/小值 max()/min()
In [1]: max(1,2,3)
Out[1]: 3

In [2]: max([1,2,3])
Out[2]: 3

In [3]: max((1,2,3))
Out[3]: 3

In [4]: max({1,2,3})
Out[4]: 3

In [5]: max({1:3, 2:2, 3:1})
Out[5]: 3

In [6]: max({1:333, 2:222, 3:111})
Out[6]: 3

In [7]: max(a, b, c)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[7], line 1
----> 1 max(a, b, c)

NameError: name 'a' is not defined

In [8]: max(A,a)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[8], line 1
----> 1 max(A,a)

NameError: name 'A' is not defined
  • 求和 sum()
  • 科学计算库 math、numpy、scipy
import math # 导入库
print(math.exp(1)) # 指数运算
print(math.log2(2)) # 对数运算
print(math.sqrt(4)) # 开平方运算

# output
2.718281828459045
1.0
2.0

import numpy as np
a = [1,2,3,4,5]
print(np.mean(a)) # 求平均值
print(np.median(a)) # 求中位数
print(np.std(a)) # 求标准差

# output
3.0
3.0
1.4142135623730951

2.2 字符串

2.2.1 字符串的成倍复制

Str * n 或 n * Str

a = '----21'
b = 'can you do something for me----'
c = a + b
print(c * 3)
print('\n')
print(3 * c)

# output
----21can you do something for me--------21can you do something for me--------21can you do something for me----


----21can you do something for me--------21can you do something for me--------21can you do something for me----

2.2.2 判断子集是否在字符串内 in

Str = 'hello, my name is ryan.'
str1 = 'hello'
str2 = 'Hello'
print(str1 in Str) # True
print(str2 in Str) # False

2.2.3 字符编码

将中文字库,英文字母、数字、特殊字符等转化成计算机可识别的二进制数

::: tips

  1. Python 中使用的是 Unicode 编码
  2. 每个单一字符对应一个唯一的互不重复的二进制编码

:::

  1. 将字符转化为 Unicode 码 ord()
print(ord('1'))
print(ord('2'))
print(ord('a'))
print(ord('你'))
print(ord('坏'))

# output
49
50
97
20320
22351
  1. 将 Unicode 码转化为字符 chr()
print(chr(1010))
print(chr(10000))
print(chr(12345))
print(chr(23456))

# output
ϲ
✐
〹
宠

2.3 布尔型

2.3.1 判断是否全为真/假 any()all()

3. 组合数据类型

3.1 列表

range()

range(起始数字,结束数字(不包含),步长)

  1. 必须包含终止位置
  2. 默认起始数字是 0
  3. 默认步长是 1
  • range() 就这两种写法:
for i in range(5):
    print(i)

# output
0
1
2
3
4

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

# output
1
2
3
4
  • range() 转其他数据类型
lst1 = list(range(1, 6, 1))
lst2 = tuple(range(1, 6, 1))
lst3 = set(range(1, 6, 1))
lst4 = str(range(1, 6, 1)) # 不可以


print(lst1, lst2, lst3, lst4, sep = '\n')

# output
[1, 2, 3, 4, 5]
(1, 2, 3, 4, 5)
{1, 2, 3, 4, 5}
range(1, 6)

3.2 元组

  1. zip

  2. 返回值不止一个的函数,默认返回一个元组

def f(x):
    return pow(x,2), pow(x,3), pow(x,4)
a = f(2)
print(a)

# output
(4, 8, 16)
def f(x):
    return pow(x,2), pow(x,3), pow(x,4)
a, b = f(2)
print(a, b)

# output
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\Coder\Python\basic_knowledge_extension\Combination_type\List.py", line 45, in <module>
    a, b = f(2)
ValueError: too many values to unpack (expected 2)
def f(x):
    return pow(x,2), pow(x,3), pow(x,4)
a, b, c = f(2)
print(a, b, c)

# output
4 8 16

3.3 字典

一些常用于列表(list)中的操作的括号中的元素位置一般在字典中用字典键取代,如:

dict1 = {11:'a', 22:'b', 33:'c'}
print(dict1[11]) # a

dict1[44] = 'd'
print(dict1) # {11: 'a', 22: 'b', 33: 'c', 44: 'd'}

del dict1[44]
print(dict1) # {11: 'a', 22: 'b', 33: 'c'}

dict1.pop(33)
print(dict1) # {11: 'a', 22: 'b'}

特殊的:

  1. key(), value(), items()

不加 list() 默认状态下,返回的东西很奇怪!

dict1 = {11:'a', 22:'b', 33:'c'}
key = dict1.keys()
value = dict1.values()
item = dict1.items()

print(key, value, item, sep = '\n')
# output
dict_keys([11, 22, 33])
dict_values(['a', 'b', 'c'])
dict_items([(11, 'a'), (22, 'b'), (33, 'c')])


keys = list(dict1.keys())
values = list(dict1.keys())
items = list(dict1.items())

print(keys, values, items, sep = '\n')
# output
[11, 22, 33]
[11, 22, 33]
[(11, 'a'), (22, 'b'), (33, 'c')]
  1. in()

即可以判断 key 也可以判断 value———— dict 不加 .value() 或 .key() 默认判断 key 值

dict1 = {11:'a', 22:'b', 33:'c'}
print(11 in dict1) # True
print(11 in dict1.keys()) # True
print(11 in dict1.values()) # False
print('a' in dict1.values()) # True
  1. popitem()

随机删除字典中的一对键与键值,一个返回变量返回元组,两个分别返回键和键值

dict1 = {11:'a', 22:'b', 33:'c', 44:'d'}
key_and_value = dict1.popitem()

print(key_and_value) 
print(dict1) 

key, value = dict1.popitem()
print(key, value, sep = '\n')

# output
(44, 'd')
{11: 'a', 22: 'b', 33: 'c'}
33
c
  1. get()

value = get()

用于输入一个 key,返回其在字典内的 value,没有该 key 则返回默认值 none 或 设置的值

dict1 = {11:'a', 22:'b', 33:'c'}
print(11) # a

print(12) # None

print(get(11, 'wtf')) # a

print(get(12, 'wtf')) # wtf

value1 = dict1.get(11)
print(value1) # a

value2 = dict1.get(11, 'wtf')
print(value2) # a

value3 = dict1.get(12)
print(value3) # None

value4 = dict1.get(12,'wtf')
print(value4) # wtf
  1. clear()
dict1 = {11:'a', 22:'b', 33:'c', 44:'d'}
dict1.clear()
print(dict1) # {}

注意

del 和 clear 的区别在于:

del dict 直接把字典 dict 删除 ,运行结果会报错

而 clear 是清空字典

dict1 = {11:'a', 22:'b', 33:'c', 44:'d'}
dict1.clear()
print(dict1) 
# output
{}


dict1 = {11:'a', 22:'b', 33:'c', 44:'d'}
del dict1
print(dict1)
# output
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\Coder\Python\basic_knowledge_extension\Data_type\dict.py", line 70, in <module>
    print(dict1)
NameError: name 'dict1' is not defined
  • 字典的嵌套使用:
  1. 列表嵌套字典

  2. 字典嵌套字典

class1 = {'tom':{'grade':1, 'age':7}, 'mike':{'grade':1,'age':8}}
print(class1['tom']['age'])
print(class1['mike']['grade'])

# output
7
1

3.4 集合

集合里元素的 “位置” 不固定,每次打印集合元素的前后顺序都是随机的

3.4.1 数学运算

数学运算的结果都是返回一个新的集合

  1. 交集 &
  2. 并集 |
  3. 两集合的非交集部分 ^
  4. 补集(在前者但不在后者)-

3.4.2 操作

  • 增删元素 add(), remove()
starts = {'a', 'b', 'c'}
starts.add('d')
print(starts)
starts.remove('d')
print(starts)

# output
{'a', 'b', 'd', 'c'}
{'a', 'b', 'c'}

4. 程序控制结构

4.1 条件测试

4.1.1 非空

数据结构不为空,变量不为 0、none、False 则条件成立

a = [1]
if a:
    print('非空')
else:
    print('空的')

4.1.2 逻辑运算

  • 与、或、非
  • and
  • or
  • not
a = 10
b = 8
c = 12
print((a>b) and (b>c)) # 与
print((a>b) or (b>c)) # 或
print(not(a>b)) # 非   

# output
False
True
False
  • 优先级:not>and>or
print(True or True and False)
print((True or True) and False)

# output
True
False

4.1.3 存在运算

  • in
cars = ['byd', 'bmw', 'audi', 'toyota']
print('bmw' in cars)
print('bens' in cars)

# output
True
False
  • not in
cars = ['byd', 'bmw', 'audi', 'toyota']
print('bmw' not in cars)
print('bens' not in cars)

# output
False
True

4.2 遍历循环

4.2.1 变换迭代————字典

students = {201901: '小明', 201902: '小红', 201903:'小强'}
for k, v in students.items(): # key & value
    print(k, v)
for v in students.values(): # value
    print(v)
for k in students.keys(): # keys
    print(k)
    
# output
201901 小明
201902 小红
201903 小强
小明
小红
小强
201901
201902
201903

4.2.2 range() 对象

  • range(起始:结束(该数字不包括):步长)
res = []
for i in range(10000):
    res.append(i ** 2)
print(res[:5]) # [0, 1, 4, 9, 16]
  • range() 也是左闭右开!
res = []
for i in range(1,10,2):
    res.append(i ** 2)
print(res) # [1, 9, 25, 49, 81]

4.2.3 for 和 else 配合:

product_scores = [89, 90, 99, 70, 67, 78, 85, 92, 77, 82]
"""
一组十个的产品,其性能评分如果低于七十五分的超过一个,则该组产品不合格
"""
i = 0
for score in product_scores:
    if score < 75:
        i += 1
    if i == 2:
        print('产品不合格')
        break
else:
    print('产品抽检合格')

4.2.4 while 和 else 融合:

count = 0
while count <= 4:
    count += 1
    print(count)
else:
    print("循环正常执行啦")
    
    
# output
1
2
3
4
5
循环正常执行啦

4.3 控制语句注意问题

  • 减少多层嵌套

  • 避免死循环

  • 封装过于复杂的判断条件

如果条件判断里的表达式过于复杂,出现多次的 not/and/or 等

会导致可读性大打折扣———— 考虑将条件封装为函数

a, b, c, d, e = 10, 8, 6, 2, 0
if (a > b) and (c > d) and (not e)
    print("太复杂了!")

numbers = (10, 8, 6, 2, 0)
def judge(num):
    a, b, c, d, e = num
    x = a > b
    y = c > d
    z = not e
    return x and y and z

if judge(numbers):
    print('nice!')

# nice!

5. 函数

5.1 关键字参数与位置参数

关键字参数

  • 严格按照位置顺序,用实参对形参进行赋值(关联)
def function(x,y,z):
    print(x, y, z)
function(1, 2, 3)

位置参数

  • 打破位置限制,直呼其名的进行值的传递
function(y=1, z=2,x=3)

两者可以混用,但是关键字参数必须放在位置参数后面

function(1, z=2, y=3)
function(1, 2, z=3)

5.2 默认参数

  • 提前在函数里设定好的值————必须放在非默认参数后面!!!
def register(name, age, sex='male'): # sex 有默认值,一定要放最后
    print(name, age, sex)

register('ryan', 19)
# output
ryan 19 male
  • 或者可以直接传值————直接修改默认值
def register(name, age, sex='male'):
    print(name, age, sex)

register('ryan', 19)
register('winter',22, 'female')
# output

ryan 19 male
winter 22 female

默认参数应该设置为不可变的类型(数字、字符串、元组)

  • 默认参数应该设置为不可变的类型

否则:

def function(ls=[]):
    print(id(ls))
    ls.append(1)
    print(id(ls))
    print(ls)

function()
function()
function()

# output
1903176266176
1903176266176
[1]
1903176266176
1903176266176
[1, 1]
1903176266176
1903176266176
[1, 1, 1]

所以应该:

def function(ls='Python'):
    print(id(ls))
    ls += '3.7'
    print(id(ls))
    print(ls)
    
function()
function()
function()

# output
2334782625648
2334787222576
Python3.7
2334782625648
2334787222512
Python3.7
2334782625648
2334787222576
Python3.7
  • 利用默认参数决定参数是否加入函数中
def name(first_name, last_name, middle_name=None): # middle_name 默认是没有的,只有用户输入 middle_name 才会有
    if middle_name:
        return first_name + middle_name + last_name
    else:
        return first_name + last_name

print('l','j')
print('l','x','j')

# output
l j
l x j

5.3 可变参数

  1. *args

必须放在参数最后

def function(x, y, z,  *args):
    print(x, y, z)
    print(args)

function(1, 2, 3, 4, 5, 6)

# output
1 2 3
(4, 5, 6)
  1. 实参拆分
def function(x, y, z,  *args):
    print(x, y, z)
    print(args)

function(1, 2, 3, [1,2,3])

# output
1 2 3
([1, 2, 3],)

def function(x, y, z,  *args):
    print(x, y, z)
    print(args)

function(1, 2, 3, 'hello')

# output
1 2 3
('hello',)

给列表、字符串、元组、集合拆分

def function(x, y, z,  *args):
    print(x, y, z)
    print(args)

function(1, 2, 3, *[4, 5, 6])

# output
1 2 3
(4, 5, 6)

def function(x, y, z,  *args):
    print(x, y, z)
    print(args)

function(1, 2, 3, *'hello')

# output
1 2 3
('h', 'e', 'l', 'l', 'o')
  1. 可变长参数 **kwargs
def function(x, y, z, **kwargs):
    print(x, y, z)
    print(kwargs)

function(1, 2, 3, a= 1, b = 2, c = 3 )

# output
1 2 3
{'a': 1, 'b': 2, 'c': 3} # 多余参数以字典形式打包传递给 kwargs 

字典实参拆分

def function(x, y, z, **kwargs):
    print(x, y, z)
    print(kwargs)

function(1, 2, 3, **{'a':1, 'b':2, 'c':3})

# output
1 2 3
{'a': 1, 'b': 2, 'c': 3}

5.4 全局变量

  • 在函数外定义的变量
  • 全局变量在函数体内直接被使用
n = 3
ls = [0]
def multipy(x, y):
    z = n*x*y
    ls.append(z)
    return z

print(multipy(2, 9))
print(ls)

# output
54
[0, 54]

5.4.1 通过 global 在函数体内定义全局变量

# 没有设置全局变量
def multipy0(x, y): 
    z = x*y 
    return z
print(multipy0(2, 9))
print(z)

# output
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\Coder\Python\basic_knowledge_extension\function\function.py", line 126, in <module>
    print(z)
NameError: name 'z' is not defined





# 设置为全局变量
def multipy1(x, y):
    global z
    z = x*y
    return z

print(multipy1(2, 9))
print(z)

# output
18
18

5.5 返回值

  1. 单个返回值
def function(x):
    return x**2

print(function(2))

# output
4
  1. 多个返回值
  • 以元组形式返回
def function(x):
    return x, x**2, x**3

print(function(2))

# output
(2, 4, 8)
  • 拆分赋值
def function(x):
    return x, x**2, x**3

a, b, c = function(2)
print(a, b, c)
# output
2 4 8
  1. 没有 return 语句, 返回值为 None
def function():
    print('hello')

a = function()
print(a)

# output
hello
None

5.6 匿名函数

基本形式:

lambda 变量: 函数体

f = lambda: 'Hello world'
print(f())

# output
Hello world
x = lambda a: a+10
print(x(1))

# output
11
x = lambda a, b, c: a + b + c
print(x(1, 2, 3))

# output
6
numbers = [1, 2, 3, 4, 5, 6]
squared = list(map(lambda x: x**2, numbers))
print(squared)

# output
[1, 4, 9, 16, 25, 36]

扩展使用方法:

  1. sort, sorted
ls = [(7,2),(5,4),(3,6),(1,8)]
ls.sort()
print(ls)

ls.sort(key = lambda x: x[1] )
print(ls)

ls_sorted = sorted(ls, key = lambda x: x[0] + x[1], reverse = True)
print(ls_sorted)

# output
[(1, 8), (3, 6), (5, 4), (7, 2)]
[(7, 2), (5, 4), (3, 6), (1, 8)]
[(7, 2), (5, 4), (3, 6), (1, 8)]
  1. max, min
ls = [(7,2),(5,4),(3,6),(1,8)]
n = max(ls, key = lambda x: x[1])
m = min(ls, key = lambda x: x[0] + x[1])

print(m, n)

# output
(7, 2) (1, 8)

6. 类

6.1 类的定义

三要素:类名、属性、方法

6.1.1 类的命名

  • 要有实际意义
  • 驼峰命名法,如 CreditCard
"""类前空两行"""

class car():
    """对该类进行简单介绍"""
    pass

"""类后空两行"""

6.1.2 类的属性

# def __init__(self,要传递的参数) 初始化类的属性


class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand # 汽车的品牌
        self.model = model # 汽车的属性
        self.year = year # 汽车出厂年份
        self.mileage = 0 # 新车总里程初始化为 0     

6.1.3 类的方法

可以理解为类内部函数



class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand # 汽车的品牌
        self.model = model # 汽车的属性
        self.year = year # 汽车出厂年份
        self.mileage = 0 # 新车总里程初始化为 0
    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)
        
        

6.2 创建实例

6.2.1 实例的创建

将实例赋值给对象、实例化过程中,传入相应的参数

v = 类名(必要的初始化参数)

 my_new_car = car('audi', 'a6', 2018)

6.2.2 访问属性

实例名.属性名

print(my_new_car.brand)
print(my_new_car.model)
print(my_new_car.year)

# output
audi
a6
2018

6.2.3 调用方法

class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)

品牌:audi 型号:a6 出厂年份:2018

mileage = my_new_car.get_mileage()
print(mileage)

行车总里程: 0公里

6.2.4 修改属性

  1. 直接修改
class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)

# 先访问
my_old_car = car('byd', '陆', 2016)

# 后修改
print(my_old_car.mileage) # 0
my_old_car.mileage = 99999

# 查看修改效果
print(my_old_car.mileage) # 99999
print(my_old_car.get_mileage()) # 行车总里程: 99999公里
  1. 创建一个新的方法修改
class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)
    
    
my_old_car = car('byd', '陆', 2016)
print(my_old_car.get_mileage()) # 行车总里程: 0公里
my_old_car.set_mileage(8000)
print(my_old_car.get_mileage()) # 行车总里程: 8000公里
  1. 继续拓展
  • 禁止设置负里程
class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)

    def set_mileage(self, distance):
        """设置总里程数"""
        if distance >= 0:
            self.mileage = distance
        else:
            print("里程数不可设置为负")
my_old_car = car('byd', '陆', 2016)

my_old_car.set_mileage(-8000)
print(my_old_car.get_mileage()) 

# output
里程数不可设置为负
行车总里程: 0公里
  • 将每次的里程数增加
class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)

    def set_mileage(self, distance):
        """设置总里程数"""
        if distance >= 0:
            self.mileage = distance
        else:
            print("里程数不可设置为负")

    def increment_mileage(self, distance):
        """总里程数累计"""
        if distance >= 0:
            self.mileage += distance
        else:
            print("新增里程数不能为负")
my_old_car = car('byd', '陆', 2016)

print(my_old_car.get_mileage())
my_old_car.set_mileage(9999)
my_old_car.increment_mileage(90000)
print(my_old_car.get_mileage())

# output
行车总里程: 0公里
行车总里程: 99999公里

6.3 类的继承

6.3.1 简单的继承

父类

class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)

    def set_mileage(self, distance):
        """设置总里程数"""
        if distance >= 0:
            self.mileage = distance
        else:
            print("里程数不可设置为负")

    def increment_mileage(self, distance):
        """总里程数累计"""
        if distance >= 0:
            self.mileage += distance
        else:
            print("新增里程数不能为负")

my_old_car = car('byd', '陆', 2016)


my_old_car.set_mileage(9999)
my_old_car.increment_mileage(90000)


my_new_car = car('audi', 'A6', 2018)

my_cars = [my_new_car, my_old_car]
print(my_cars)
# output
[<__main__.car object at 0x000001EB5585CF10>, <__main__.car object at 0x000001EB5585CFD0>]

子类

class 子类名(父类名):

class car():
    """模拟汽车"""

    def __init__(self, brand, model, year):
        """初始化汽车属性"""
        self.brand = brand  # 汽车的品牌
        self.model = model  # 汽车的属性
        self.year = year  # 汽车出厂年份
        self.mileage = 0  # 新车总里程初始化为 0

    def get_main_information(self):
        """获取汽车主要信息"""
        print("品牌:{} 型号:{} 出厂年份:{}".format(self.brand, self.model, self.year))

    def get_mileage(self):
        """获取总里程"""
        return "行车总里程: {}公里".format(self.mileage)

    def set_mileage(self, distance):
        """设置总里程数"""
        if distance >= 0:
            self.mileage = distance
        else:
            print("里程数不可设置为负")

    def increment_mileage(self, distance):
        """总里程数累计"""
        if distance >= 0:
            self.mileage += distance
        else:
            print("新增里程数不能为负")
  • 创建子类:
class Elecriccar(car):
    """模拟电动汽车"""
    def __init__(self, brand, model, year):
    """初始化电动汽车属性"""
    super().__init__(brnad, model, year) # 声明继承父类的属性
  • 已经包含父类的所有方法:
my_electric_car = Elecriccar('Nextweek', 'FF91', 2046)
my_electric_car.get_main_information()

品牌:Nextweek 型号:FF91 出厂年份:2046

6.3.2 给子类添加属性和方法

class Elecriccar(car):
    """模拟电动汽车"""
    def __init__(self, brand, model, year, bettery_size):
        """初始化电动汽车属性"""
        super().__init__(brand, model, year) # 声明继承父类的属性
        self.bettery_size = bettery_size # 电池容量
        self.electric_quantity = bettery_size # 电池剩余数量
        self.electric_distance_ratio = 5 # 电量距离换算系数 5 公里/kw.h
        self.remainder_range = self.electric_quantity*self.electric_distance_ratio # 剩余可行驶里程

    def get_electric_quantity(self):
        """查看当前电池电量"""
        print("当前电池的电量: {} Kw.h".format(self.electric_quantity))

    def set_electric_quantity(self, electric_quantity):
        """设置电池剩余电量,重新计算电量可支撑行驶里程"""
        if electric_quantity >= 0 and electric_quantity <= self.bettery_size:
            self.electric_quantity = electric_quantity
            self.remainder_range = self.electric_quantity*self.electric_distance_ratio
        else:
            print("电量未设置在合理范围之内")
    def get_remainder_range(self):
        """查看剩余可行驶里程"""
        print("当前电量还可以继续行驶 {} 公里".format(self.remainder_range))
my_electric_car = Elecriccar('nextweek', 'FF91', 2046, 70)
my_electric_car.get_electric_quantity() # 获取当前电池电量
my_electric_car.get_remainder_range() # 获取当前剩余可行使里程

当前电池的电量: 70 Kw.h 当前电量还可以继续行驶 350 公里

my_electric_car.set_electric_quantity(50) # 重设电池电量
my_electric_car.get_electric_quantity() # 获取当前电池电量
my_electric_car.get_remainder_range() # 获取当前剩余可行驶里程

当前电池的电量: 50 Kw.h 当前电量还可以继续行驶 250 公里

6.3.3 重写父类的方法————多态

原先:

my_electric_car.get_main_information(

品牌:nextweek 型号:FF91 出厂年份:2046

修改后:

class Elecriccar(car):
    """模拟电动汽车"""
    def __init__(self, brand, model, year, bettery_size):
        """初始化电动汽车属性"""
        super().__init__(brand, model, year) # 声明继承父类的属性
        self.bettery_size = bettery_size # 电池容量
        self.electric_quantity = bettery_size # 电池剩余数量
        self.electric_distance_ratio = 5 # 电量距离换算系数 5 公里/kw.h
        self.remainder_range = self.electric_quantity*self.electric_distance_ratio # 剩余可行驶里程

    def get_main_information(self): # 重写父类方法
        """获取汽车主要信息"""
        print("品牌:{}, 型号:{}, 出厂年份:{}, 续航里程:{} 公里".format(self.brand, self.model, self.year, self.bettery_size*self.electric_distance_ratio))

    def get_electric_quantity(self):
        """查看当前电池电量"""
        print("当前电池的电量: {} Kw.h".format(self.electric_quantity))

    def set_electric_quantity(self, electric_quantity):
        """设置电池剩余电量,重新计算电量可支撑行驶里程"""
        if electric_quantity >= 0 and electric_quantity <= self.bettery_size:
            self.electric_quantity = electric_quantity
            self.remainder_range = self.electric_quantity*self.electric_distance_ratio
        else:
            print("电量未设置在合理范围之内")
    def get_remainder_range(self):
        """查看剩余可行驶里程"""
        print("当前电量还可以继续行驶 {} 公里".format(self.remainder_range))
my_electric_car = Elecriccar('nextweek', 'FF91', 2046, 70)
my_electric_car.get_main_information()

品牌:nextweek, 型号:FF91, 出厂年份:2046, 续航里程:350 公里

6.3.4 用在类中的实例

把电池抽象成一个对象

逻辑更加清晰

7. 文件、异常和模块

7.1 文件的读写

7.1.1 文件的代开通用格式

with open("文件路径","打开模式", encoding = '操作文件的字符编码') as f:
    '对文件进行相应的读写操作'

使用 with 块的好处:执行完毕后,自动对文件进行 close 操作。

  • 实例:
with open('E:\ipython\测试文件.txt', 'r', encoding = 'gbk') as f: # 第一步:打开文件
    text = f.read() # 第二步:读取文件
    print(text)
  1. 文件路径
  • 完整路径
  • 程序与文件在同一文件夹,可简化成文件名
with open('测试文件.txt', 'r', encoding = 'gbk') as f:
  1. 打开模式
模式功能/效果
r 只读模式如文件不存在,则报错
w 覆盖写模式如文件不存在,则创建;如文件存在,则完全覆盖原文件
x 创建写模式如文件不存在,则创建;如文件存在,则报错
a 追加写模式如文件不存在,则创建;如文件存在,则在原文件后追加内容
b 二进制文件模式不能单独使用,需要配合使用如‘rb’,‘wb’,‘ab’,该模式不需指定 encoding
t 文本文件模式默认值,需配合使用如‘rt’,’wt‘,’at',一般省略,简写成‘r’,‘w’,‘a’
+与‘r’,‘w',’x',‘a' 配合使用,在原功能基础上,增加读写功能
  1. 字符编码
  • 万国码 utf-8

包含全世界所有国家地区需要用到的字符

  • 中文编码 gbk

专门解决中文编码问题

  • windows 中文系统下,如果缺省,则默认为 gbk(所在区域的编码)

注意

为了清楚起见,除了处理二进制文件,尽量不要缺省 encoding

7.1.2 文件的读取

  1. 读取整个内容————f.read()
with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f: # 第一步:打开文件
    text = f.read() # 第二步:读取文件
    print(text)

# output
临江仙·滚滚长江东逝水
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
  • ‘r’ 在正常情况下可以缺省
with open("D:\AI-learning\三国演义片头曲.txt", encoding = 'utf-8') as f: # 第一步:打开文件
    text = f.read() # 第二步:读取文件
    print(text)

# output
临江仙·滚滚长江东逝水
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
  • 解码模式不匹配
with open("D:\AI-learning\三国演义片头曲.txt", encoding = 'gbk') as f:
    text = f.read()
    print(text)

# output

Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\Coder\Python\basic_knowledge_extension\function\functionhomework.py", line 38, in <module>
    text = f.read()
UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 50: illegal multibyte sequence
  1. 逐行进行读取————f.readline()
with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
    text = f.readline() # 只读取一行
    print(text) # 临江仙·滚滚长江东逝水
with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
    for i in range(3):
        text = f.readline()
        print(text) 
    print(text)
    
# output
临江仙·滚滚长江东逝水

滚滚长江东逝水,浪花淘尽英雄。

是非成败转头空。

是非成败转头空。
with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
    while True:
        text = f.readline()
        if not text: # 文章读取完末尾段行后,再继续读取就是空行
            break
        else:
            # print(text == '\n')
            print(text, end='') # 保留原行的换行,使 print() 的换行不起作用

# output
临江仙·滚滚长江东逝水
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
  1. 读入所有行,以每行为元素形成一个列表————f.readlines()
with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
    text = f.readlines() # 注意每行末尾有换行符
    print(text)

# output
['临江仙·滚滚长江东逝水\n', '滚滚长江东逝水,浪花淘尽英雄。\n', '是非成败转头空。\n', '青山依旧在,几度夕阳红。\n', '白发渔樵江渚上,惯看秋月春风。\n', '一壶浊酒喜相逢。\n', '古今多少事,都付笑谈中。']
  • 通过循环,输出列表中元素
with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
    for text in f.readlines():
        print(text, end = '')
       
# output
临江仙·滚滚长江东逝水
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
  1. 小结: 文件比较大时, read()   readlines()  占用内存过大,不建议使用

​ 而 readline 使用起来又不太方便————直接使用

​ f 本身就是一个可迭代对象,每次迭代读取一行内容

with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
    for text in f: # f 本身就是一个可迭代对象,每次迭代读取一行内容
        print(text, end='')
        
# output
临江仙·滚滚长江东逝水
滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
  1. 二进制文件
with open("D:\AI-learning\三国演义片头曲.txt", 'rb') as f:
    print(len(f.readlines()))

7.1.3 文件的写入

  1. 像文件写入一个字符串——f.write()
with open("D:\AI-learning\文本文档.txt", 'w', encoding = 'utf-8') as f:
    f.write('你曾经对我说\n') # 文件不存在则立刻创建一个
    f.write('你永远爱着我\n') # 如需换行,末尾加换行符\n
    f.write('爱情这东西我明白\n')
    f.write('但永远时什么\n')

with open("D:\AI-learning\文本文档.txt", 'a', encoding = 'utf-8') as f:
    f.write('姑娘你别哭泣\n')
    f.write('我俩还在一起\n')
    f.write('今天的欢乐\n')
    f.write('将是明天创痛的回忆\n')

with open("D:\AI-learning\文本文档.txt", 'r', encoding = 'utf-8') as f:
    text = f.read()
    print(text)
    
# output
你曾经对我说
你永远爱着我
爱情这东西我明白
但永远时什么
姑娘你别哭泣
我俩还在一起
今天的欢乐
将是明天创痛的回忆
  1. 将一个元素为字符串的列表整体写入文件——f.writelines()
lst = ['so baby pull me closer\n', 'in the backseat of your rover,\n', 'that I know you can not afford']
with open("D:\AI-learning\文本文档.txt", 'a', encoding ='utf-8') as f:
    f.writelines(lst)

with open("D:\AI-learning\文本文档.txt", 'r', encoding = 'utf-8') as f:
    text = f.read()
    print(text)
# output
so baby pull me closer
in the backseat of your rover,
that I know you can not afford

7.1.4 既读又写

编辑文本和阅读文本常常是同时需要的,那么‘r+’,‘w+’,‘a+’ 才可以满足我们的需要

下面介绍一个在此处常用的函数:

相关信息

.seek(step:position)

step: 光标要移动的步数

position: 光标的初始位置(0,1,2)————‘0’ 代表文本开头,‘1’代表当前位置,‘2’代表文本末尾

  1. ‘r+’
  • 如果文件名不存在则报错
  • 指针在开始
  • 要把指针移到末尾才能开始写,否则会覆盖前面内容

查看文件后想编写文章内容:

with open("D:\AI-learning\文本文档.txt", 'r+', encoding='utf-8') as f:
    f.seek(0,2) # 将指针指到文章末尾
    text = ['我的名字叫做 ryan \n', '初次见面请多关照。\n']
    f.writelines(text)

你好 你是谁? 我的名字叫做 ryan 初次见面请多关照。

  1. ‘w+’
  • 若文件不存在,则创建
  • 若文件存在,则会立刻清空原本内容!!!

覆盖写文件后想查看全部文本:

with open("D:\AI-learning\文本文档.txt", 'w+', encoding = 'utf-8') as f:
    text = ["winter is ryan's girlfriend\n", "金旼炡是陆兴久的女友\n"]
    f.writelines(text) # 写完文本,指针在结尾
    f.seek(0,0) # 移动指针到开头
    print(f.read()) # 阅读全文

# output
winter is ryan's girlfriend
金旼炡是陆兴久的女友
  1. ‘a+’
  • 若文件不存在,则创建
  • 指针在末尾,添加新内容,不会清空原内容

添加写文件后想查看全部文本:

with open("D:\AI-learning\文本文档.txt", 'a+', encoding = 'utf-8') as f:
    text = ["ryan is winter's boyfriend\n", "陆兴久是金旼炡的男友\n"]
    f.writelines(text) # 写完文本,指针在结尾
    f.seek(0,0) # 移动指针到开头
    print(f.read()) # 阅读全文

# output
winter is ryan's girlfriend
金旼炡是陆兴久的女友
ryan is winter's boyfriend
陆兴久是金旼炡的男友

7.1.5 数据的存储与读取

通用的数据格式,可以在不同语言中加载和存储

以下讲解一些比较简单的数据存储结构 csv 和 json

  1. csv 格式

由逗号将数据分开的字符序列,可以由 excel 打开

  • 读取
  • 写入

也可以借助 csv 模块完成上述操作

  1. json 格式

常被用来存储字典

  • 写入——dump()
  • 读取——load()

7.2 异常处理

7.2.1 常见异常的产生

  1. 除0运算——ZeroDivisionError
1/0
  1. 找不到可读文件——FileNotFoundError
with open('nobody.csv') as f:
        pass
  1. 值错误——ValueError

​ 传入一个不期望的值

s = '1.3'
n = int(s)
  1. 索引错误——IndexError

​ 下标超出序列边界

lst = [1, 2, 3]
print(lst[3])
  1. 类型错误——TypeError

​ 传入对象与要求类型不符

1 + '3'
  1. 其他常见类型

​ NameError 使用一个为被定义的变量

​ KeyError 试图访问字典里不存在的键

print(a)
dic = {}
print(dic['a'])

7.2.2 异常的处理

提高程序的稳定性和可靠性

  1. try + except

    1. 如果 try 内代码块顺利执行,except 不被触发

    2. 如果try 内代码块发生错误,触发 except ,执行 except 内代码块

  • 单分支

判断对了

x = 10
y = 0
try:
    z= x/y
except ZeroDivisionError:
    print('0 不可以被除!')
    
# output
0 不可以被除!

判断错了

x = 10
y = 0
try:
    z= x/y
except NameError:
    print('0 不可以被除!')

# output
Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\Coder\Python\basic_knowledge_extension\function\functionhomework.py", line 187, in <module>
    z= x/y
ZeroDivisionError: division by zero
  • 多分支
lst = []
d = {'name':'ryan'}
try:
    y = m
    lst[1]
    d['sex']
except NameError:
    print("变量名不存在")
except IndexError:
    print("索引超出界限")
except KeyError:
    print("键不存在")
    
# output
变量名不存在
lst = []
d = {'name':'ryan'}
try:
    # y = m
    lst[1]
    d['sex']
except NameError:
    print("变量名不存在")
except IndexError:
    print("索引超出界限")
except KeyError:
    print("键不存在")

# output
索引超出界限

得出结论:多分支只可检测单个问题

  • 万能的异常 Exception
lst = []
d = {'name': 'ryan'}
try:
    lst[2]
except Exception:
    print("出错了")
    
# output
出错了

如何捕获异常的值 ————as

lst = []
try:
    lst[1]
except Exception as e:
    print(e)

dic = {'b':1}
try:
    dic['a']
except Exception as e:
    print(e)

try:
    b = 1/0
    print(b)
except Exception as e:
    print(e)

try:
    s = '1.3'
    n = int(s)
except Exception as e:
    print(e)

try:
    1 + '3'
except Exception as e:
    print(e)
    
# output
list index out of range
'a'
division by zero
invalid literal for int() with base 10: '1.3'
unsupported operand type(s) for +: 'int' and 'str'
  1. try + except + else

如果 try 模块成功执行,那么 else 模块也执行

try:
    with open("D:\AI-learning\三国演义片头曲.txt", 'r', encoding = 'utf-8') as f:
        text = f.read()
        print(len(text))
except FileNotFoundError:
    print("找不到文件")
else:
    for s in ['\n', ',','。','?']: # 去除换行符和标点符号
        text = text.replace(s,'')
    print('三国演义片头曲共由{}个字组成'.format(len(text)))

# output
87
三国演义片头曲共由71个字组成
  1. try + except + finally

不论 try 模块是否执行,finally 最后都执行

ls = []
d = {'name':'ryan'}
try:
    y = m
except Exception as e:
    print(e)
finally:
    print("不论正不正常,都将执行")
    
# output
name 'm' is not defined
不论正不正常,都将执行

7.3 模块简介

7.3.1 广义模块分类

  1. python 内置

时间库 time \ 随机库 random \ 容器数据类型 collection \ 迭代器函数 itertools

  1. 第三方库

数据分析 numpy、pandas \ 数据可视化 matplotlib \ 机器学习 scikit-learn \ 深度学习 Tensorflow

  1. 自定义文件

    1. 单独 py 文件
    2. 包———多个 py 文件
    # 文件夹内多个 py 文件,再加一个__init__.py 文件(内容可为空)
    
你认为这篇文章怎么样?
  • 0
  • 0
  • 0
  • 0
  • 0
  • 0
评论
  • 按正序
  • 按倒序
  • 按热度