Python基础语法学习总结

实验目的

学习Python基本语法

实验场地与设备

线上

实验方式

阅读教程与程序设计

实验设计

Python语言基础

图1.1 Python基础语法学习实验设计

实验内容

Python语法总结

Python基本语法

基本语句

① 首先是输入输出语句,输入语句比较简单为name=input(),基本输出语句为print(),拼接输出使用逗号。

② 注释采用# 进行书写

③ 代码风格:Python采用的是缩进式代码风格,所以对于复制粘贴比较不友好

④ 条件判断语句:if 条件1 :...elif 条件2 : ... else : ...

⑤ 循环语句:

第一种是for循环:for x in []: for x in ...: 循环就是把每个元素代入变量x,然后执行缩进块的语句

第二种是while循环:while 条件判断语句 : breakcontinue和java中用法相同

数据类型

① 整数:对于很大的数,很难数清楚0的个数。Python允许在数字中间以_分隔。

② 浮点数:允许使用科学计数法定义

③ 字符串:在Python没有严格要求'' ""的区别在,也就是说没有区分字符和字符串使用二者没有任何区别。

  • 转义符和Java中保持一致
  • Python允许用r''表示''内部的字符串默认不转义

④ 布尔值:

在Python中要注意:TrueFalse要注意开头首字母大写。
可以进行与、或、非的运算,运算符分别为:andornot

⑤ 空值:空值用None表示,意义与Java中的null相同。

⑥ list:

list是Python内置的一种数据类型,list是一种有序的集合,可以随时添加和删除其中的元素。此数据类型在Java的实用类中有封装。list和数组很像,声明方式如下:

1
classname = ['老六','老八','老九']

想要调取其中的某个元素也和数组一致,赋值修改等也相同
下面列举一下list的ADT

1
2
3
4
5
6
list:
append('Elem') # 在末尾添加新的元素
insert(i,'Elem') # 将元素插入指定位置
pop() # 删除末尾元素
pop(i) # 删除i处的元素
len(list) # list列表的长度

list允许混合类型,也允许list嵌套,从而出现多维数组。

⑦ tuple

tuple被称为元组,其最大的特点就是不可修改,声明方式如下:

1
classname = ('老六','老八','老九')

tuple在定义时要确定元素个数,这里有一个问题,在定义只有一个元素的tuple时,Python语法会认为这是一个小括号,因此在定义一个元组的tuple时,要加一个,避免歧义。

1
t=(1,)

⑧ 字典(dict)

字典全称为dictionary,在Java实用类中叫hash map。其由键值对(key-value)组成,查找速度快。 下面是一种初始化方法:

1
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}

也可以放入指定的key中:

1
d['Adam'] = 67

查找value:

1
d['Adam']

key与value是多对一的关系,key需要是一个不可变对象保证key做hash运算后的唯一性。如果多次对某个key赋值,后边的value会覆盖前面的value 提供了几个函数:

  1. 通过in来判断key是否在dict中,返回值为布尔值,格式为:key in dict
  2. get()方法,dict.get('key',空返回值)key不存在时返回空返回值,空返回值可自定义,如果没有定义的话返回None
  3. pop()方法,删除key,如果有value也一并删除,格式为pop('key')

⑨ 集合(set)

set是一组key的集合,集合特点;无序性、确定性、互异性
要创建一个set,需要提供一个list作为输入集合:

1
s = set([1, 2, 3])
  • 方法:
    add(key)添加一个新的元素
    remove(key)删除一个元素
  • 两个set可以做交运算和并运算:
    交运算:s1&s2
    并运算:s1|s2

理解变量

在Python中变量仅仅是一个一个字母,变量与所对应的值之间的关系靠指针联系起来的。所以很重要的一点就是:当我们使用变量时,更多的要关注变量指向的东西,他可能是值,也可能是一个函数,也可能是一个变量

模块

模块导入

1
import numpy as np

模块下载

模块下载有比较复杂的方法,也有比较傻瓜式的。先说复杂的,使用Python中自带的pip包管理工具,用命令:

1
pip install numpy

但是使用pip需要事先了解要导的包的名字,而且不能批量导入,而且在Python编程里也有编程一分钟,导包一小时的说法。pip下载第三方库的源可能会很慢或者失效,需要会自己添加国内的高速镜像。

傻瓜式的导包,例如在pycharm中可以直接在代码中写出自己需要的包,然后交给pycharm自己去下载,或者用Anaconda提前构建好的Python的库环境。

函数式编程

函数

① 函数定义

在Python中定义函数为,def 函数名(参数):然后,在缩进块中编写函数体,函数的返回值用return语句返回。
如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。return None可以简写为return。

1)空函数:

1
2
def nop():
pass

在这里pass作为占位符,表示跳过,也可以用在if的缩进块。

2)参数限制:

1
2
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')

实际上参数限制就是定义一个报错,isinstance()判断数据类型,如果不是就提出一个错误。 作为一个弱类型语言,定义这一步是很有必要的,有助于读懂代码。

3)返回值:

Python允许返回多个值,其返回的实际上是一个tuple元组,但是也可以用两个变量接收。

② 参数定义

在Python中函数参数的定义也比较灵活,提供位置参数、默认参数、可变参数、关键字(key)参数等

1)位置参数:位置参数指的是参数在传入时,实参和形参有着严格的位置对应关系,为常用参数形式。

2)默认参数:默认参数是指在位置参数的基础上为其添加默认值,有默认值的参数为默认参数,没有默认值的参数为必选参数
基本定义形式如下:

1
2
3
def my_def(a,b=1):
a=b+1
return

需要注意的是:

  • 默认参数必须在必选参数后边,否则会无法辨认是否输入必选参数,从而报错。
  • 默认参数的默认值一定是不变对象,由于Python中的变量定义为指针指向,会导致可变对象值发生变化

3)不可变对象有:数值类型、字符串、tuple元组、None等

4)可变参数:可变参数指的是参数的数目不固定,定义形式:

1
2
3
4
5
def my_function(*v):
sum = 0
for vi in v:
sum+=vi
return sum

在可变参数中传入的所有参数将作为一个tuple被接收,该tuple的变量名为函数在定义时的形参名,定义时的需要在参数名前加一个*

5)关键字(key)参数

此处的关键字和c语言中的关键字并不是一个意义,而是在dict中的key的意义。即在传递参数时,同时传递键(key)和值(value),Python会自动封装为一个dict。

1
2
3
def my_function(**v):
print(v)
return

6)命名关键字参数

在关键字参数上,进一步限制传入的key的命名,就有了命名关键词参数:

1
2
def person(name, age, *, city, job):
print(name, age, city, job)

这里需要一个*区分位置参数与命名关键字参数,如果在这之前有可变参数,那么就不需要加*
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:

7)参数组合

在一个函数中使用多个参数要保证其中的顺序,依次为:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

1
2
def onefunction(a,b,c=0,*args,job,city,**kw):
pass

tips:

  • 使用*args**kw是Python的习惯写法。
  • 可变参数和关键字参数有一点层级的感觉,中间包裹的是命名关键字参数这个比较尴尬的参数。

③ 递归函数

写法与Java相同。

实用方法

① 切片

切片是一个针对tuple和list方便地取元素的方法,语法规则:

1
L[起始坐标:终止坐标:步长]

当起始坐标为0时可以省略;步长为1时可以省略。

② 迭代

迭代是循环的增强,但是想要弄清迭代,需要知道两件事:一个是能不能迭代,一个是迭代出的数据是什么

想要知道一个数据能否迭代可以通过一个函数来完成:

1
2
3
from collections.abc import Iterable
L=[1,2,3]
isinstance(L,Iterable)

迭代出的是什么,和要迭代的对象的储存方式,要特殊记忆一下dic。

③ 列表生成器

一种快捷生成list的方式,一个例子如下:

1
[x * x for x in range(1, 11)]

如果想要筛选生成的值,可以在for后加上if作为筛选条件,注意这里是筛选条件, 因此这里和平时的if else并不是一个东西。

1
[x * x for x in range(1, 11) if x % 2 == 0]

④ 生成器

生成器是一种惰性的计算方式。包含yield关键字,当一个函数包含yield关键字时,他就成了一个generator函数。yield在generator函数中起到了一个return的作用,即到yield便返回。 在调用时,使用一个变量接受一个generator对象。使用next()函数依次获得下一个返回值。

⑤ 迭代器

区分IterableIterator

Iterable是可迭代的,是直接可用于for循环的。包括dict、list、tuple、set、str、grenerator。
Iterator是迭代器,是直接可用于next()函数的,生成器都是Iterator对象,集合数据类型可以通过iter()获取Interator对象。

函数式编程

函数式编程是一种面向过程的编程思想,实际上是将复杂问题转化为一个个函数。

在Java的函数定义中,除去void类型不返回值,其余的都需要返回值。因此也就经常存在,使用一个变量接受函数值:

1
2
3
4
int function(x,y){
return;
}
int a=function(x,y);

那么是不是存在一种可能,我们可以将函数嵌套,让函数调用函数,让函数返回函数,彻底抛弃变量?

抛弃变量、只有函数就是彻底的函数式编程

① 理解高阶函数

之前有过变量名和值的理解,在Python中变量名和值是一个指针指向的关系。同理,函数名和函数也是这样的,函数名也是一个变量。也就是说,我们可以通过函数名,拿到函数体。也就是说函数名是什么并不重要,我们看中的是函数体。

![绘图1](https://blogpicture-1310464487.cos.ap-nanjing.myqcloud.com/ typora/%E7%BB%98%E5%9B%BE1.png)

那么设想一种情况,现在我们定义了函数f2,那么我可以随便写一个函数,然后返回一个变量f2,那么实际上我就拿到了函数体。

1
2
3
4
5
def f2(a,b):
return a+b
def f3():
return f2
print(f3()(1,2))

image-20220909173741530

然后我们在设想另一种情况,现在我们定义了另一种情况,我们在一个函数中写了一个f1作为局部变量,那么我就可以传入变量f2,然后就相当于传入了函数体。

1
2
3
4
5
def f2(a,b):
return a+b
def f1(a,b,f):
return f(a,b)
print(f1(1,2,f2))

现在就可以进行一个区分:

  • f代表函数名,是变量
  • f()代表数值,是函数的返回值,返回值是一个量

高阶函数,就是让函数的参数能够接收别的函数。

实用的几个函数,有必要查表即可

② 返回函数

同上文理解,只不过是将一个函数嵌套入了另一个函数

③ lambda表达式

与Java中语法相同,目的是为了简化返回函数嵌套

面向对象编程

类和对象

创建类:语法如下

1
class 类名(继承的类):

python的类非常随意,几乎可以不定义就能用。在类中自带有一个构造函数__init__(),此函数可以重新定义

生成对象:

1
a=A()

访问权限

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。

此外,__ __这种变量都是特殊变量,在不清楚的时候不要随便乱改

继承和多态

和Java中的思想完全相同

常用变量和方法

__slots__

用这个变量可以起到参数列表的功能,可以在一定程度上限制参数的变量名,用turple进行限定

@property

注解编程,可以起到一个简化定义setter和getter函数的作用。@property注解在getter方法上,然后会自动生成 @函数名.setter 的注解,但是要注意的一点是,在getter中就不能使用函数名作为自身的调用值,否则会出现无限的调用,产生爆栈。

③ 多继承

与Java相同

__str__:和Java中的toString方法相同

错误调试

错误处理

参照Java中,对比来学习即可:

两种方法,一是尝试,二是抛出,尝试采用:

1
2
3
4
5
6
try:
pass
except baseexception :
pass
finally:
pass

抛出采用raise关键字

测试

① 断言:assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。

如果断言失败,assert语句本身就会抛出AssertionError

② 断点:在强大IDE的辅助下,使用断点调试应该是最简单的。

实践

石头剪子布

使用random包中的random函数和条件控制语句,模拟两个电脑互相猜拳:

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

def win(pc,cc):
if (cc==1 and pc==2) or (cc==2 and pc==3)or(cc==3 and pc==1):
print("电脑一输")
elif pc==cc:
print("平")
else:
print("电脑二输")

def computer_choice():
cc=random.randint(1,3)
return cc
def show(pc,cc):
print("电脑一的出招为",pc)
print("电脑二的出招为",cc)

if __name__=="__main__":
while(True):
pc=computer_choice()
cc=computer_choice()
show(pc,cc)
win(pc,cc)

image-20220914212607801

改进提升一下:

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
import random

def win(pc,cc):
if (cc==1 and pc==2) or (cc==2 and pc==3)or(cc==3 and pc==1):
print("玩家输")
elif pc==cc:
print("平")
else:
print("玩家赢")

def computer_choice():
cc=random.randint(1,3)
return cc
def str(cc):
if cc==1:
return '石头'
elif cc==2:
return '剪刀'
else:
return '布'
def show(f,pc,cc):
print("电脑一的出招为",f(pc))
print("电脑二的出招为",f(cc))

if __name__=="__main__":
while(True):
cc=computer_choice()
print("请输入:1.石头 2.剪刀 3.布")
pc=input()
show(str,pc,cc)
win(pc,cc)

image-20220914213324805

ATM模拟

通过类和对象简单的设计了一个ATM取钱模拟器

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
64
65
66
67
68
69
70
71
72
73
74
75
import Account


class ATM(object):
def __init__(self,money,accounts):
self.money=money
self.accounts=accounts
@property
def money(self):
return self._money;
@money.setter
def money(self,value):
self._money=value
@property
def accounts(self):
return self._accounts
@accounts.setter
def accounts(self,value):
self._accounts=value

def searchId(self,id):
for account in self.accounts:
if account.id==id:
return account
def lode(self):
print('请输入账号id')
id = input()
account1 = self.searchId(id)
print('请输入密码')
password = input()
if password == account1.password:
print("欢迎", account1.name)
return account1
# 存钱
def save_money(self):
account=self.lode();
print("请输入要存入的数目")
saveMneyValue=input()
print('存款成功')
account.remain=int(account.remain)+int(saveMneyValue)
print('您的账户余额为',account.remain)
self.money=self.money+int(saveMneyValue)

# 取钱
def withdraw_money(self):
account=self.lode()
print('请输入要取出的数目')
withdrawMoneyValue=input()
if account.remain > withdrawMoneyValue:
account.remain=int(account.remain)-int(withdrawMoneyValue)
print('取款成功,您的账户余额为',account.remain)
else:
print('您的账户余额不足')
self.money=int(self.money)-int(withdrawMoneyValue)

def __str__(self):
print("当前ATM中有金额",self.money,"元")

if __name__=="__main__":
# atm1=ATM(1000)
# atm1.__str__()
# atm1.ave_money(200)
# atm1.__str__()
# atm1.withdraw_money(200)
# atm1.__str__()
accounts=[]
for i in range(5):
name=input()
id = input()
password=input()
remain=input()
accounts.append(Account.account(name, id, password, remain))
atm2=ATM(10000,accounts)
atm2.save_money()
atm2.withdraw_money()
1
2
3
4
5
6
7
8
class account(object):
def __init__(self,name,id,password,remain):
self.name=name
self.remain=remain
self.password=password
self.id=id

__slots__ = ('name','remain','password','id')

image-20220914214759256

圣诞树画图

使用Python自带的turtle包,进行圣诞树绘制:

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
import turtle

screen = turtle.Screen()
screen.setup(375, 700)

circle = turtle.Turtle()
circle.shape('circle')
circle.color('red')
circle.speed('fastest')
circle.up()

square = turtle.Turtle()
square.shape('square')
square.color('green')
square.speed('fastest')
square.up()

circle.goto(0, 280)
circle.stamp()

k = 0
for i in range(1, 13):
y = 30 * i
for j in range(i - k):
x = 30 * j
square.goto(x, -y + 280)
square.stamp()
square.goto(-x, -y + 280)
square.stamp()

if i % 4 == 0:
x = 30 * (j + 1)
circle.color('red')
circle.goto(-x, -y + 280)
circle.stamp()
circle.goto(x, -y + 280)
circle.stamp()
k += 3

if i % 4 == 3:
x = 30 * (j + 1)
circle.color('yellow')
circle.goto(-x, -y + 280)
circle.stamp()
circle.goto(x, -y + 280)
circle.stamp()

square.color('brown')
for i in range(13, 17):
y = 30 * i
for j in range(2):
x = 30 * j
square.goto(x, -y + 280)
square.stamp()
square.goto(-x, -y + 280)
square.stamp()
turtle.mainloop()

image-20220914215352995

总结

Python作为一个弱类型语言,是有他的弊端的,在一些需要数据类型转换和严格控制数据类型的情况下,会非常难受。而Python最大的优势在于有大量的库,这些库在特定的编程领域会非常便利。Python本身的语言具有极强的灵活性,而灵活性的言外之意就是规范性很难确定。因此,Python的重点是将第三方包为我所用,在数值计算中发挥他最大的作用。