文章目录
入门必学基础
1.注释
# 单行注释
'''多行注释'''
或者
"""多行注释"""
2.代码缩进
Python不像C like语言需要{}分割代码块,而是采用代码缩进和冒号区分代码层次。注意:C like语言的缩进只是一种为了美观而统一的习惯,但Py不一样,它需要严格控制缩进,缩进时一个Tab或四个空格作为一个缩进量。
对于Python,行尾的冒号和下一行的缩进表示一个代码块的开始,而缩进结束则代表一个代码块的结束。
if x>a:
print("x大于a")
else
print("x小于a")
print("缩进结束,代码块结束")
3.编码规范
- 每个import语句只导入一个模块
#推荐写法
import A
import B
#推荐写法
#不推荐写法
import A,B
#不推荐写法
2.行尾不要加分号,Python的语句不需要 ; 结尾。
3 为了提高可读性,通常在顶级定义之间空两行,方法定义空一行,某些功能的位置也可以空一行。
4.命名规范
- 模块名称:小写字母加中部下划线 game_main,game_register
- 类名:Pascal命名法,即首字母大写。
- 模块内部的类:"_" + 标识符,如BorrowBook的内部类使用_BorrowBook
- 常量命名:全部采用大写字母,可以使用下划线。
注:单下划线开头的模块变量或函数受保护,双下划綫开头的实例变量或方法是类私有的。
5.输入输出
print()函数输出。括号中可以是常量,可以是变量,也可以是" "包括的字符串,还可以是计算式,当然也可以是char()强制转换后的ASCII码。
print("这是一个输出函数")
input()函数输入。此处相当于input函数会把括号中的结果返回给这个函数。
tip = input("输入内容:")
补充:此处的print, input都是Python的内置函数,Built-in functions,简称 BIF ,而print,input就相当于Python的关键字,命名时不能以他们命名,其他关键字可以通过 dir()查询,这些都不可以用来命名,而若想知道其功能可以使用help()函数,如:
>>> help(input)
Help on built-in function input in module builtins:
input(prompt=None, /)
Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.
变量和数据类型
变量:
在Python中,不需要先声明变量名及其类型,直接复制即可创建各种类型的变量,同时,其命名也并非随意,应遵从一下原则:
- 变量名必须是一个有效的标识符
- 变量名不能使用Py中的保留字
- 慎用小写字母l和大写字母O
- 选择有意义的单词
对于保留字,可以在IDLE中输入以下代码查看:
import keyword
keyword.kwlist
注意:Py和C一样严格区分大小写。
有效的标识符:
- 由字母下划线数字组成,首位不可是数字
- 非保留字
- 区分大小写
- 注意避免使用特殊用法的标识符(如_开头表示私有的类属性)
变量使用:
number = 123
name = "法外狂徒张三"
#注意Python是动态语言,变量的类型随时可以变化
补充:type()可以返回变量类型,需要时可以用该函数查询变量类型。
基本数据类型
1.整型:
- 十进制:直接输入。在Python中高精度的运算及其方便,理论上可以输入任意位数的整数,长度不限。
- 八进制:必须以0o/0O开头。
- 十六进制:0x/0X开头。
- 二进制:直接输入,只有数字0和1.
2.浮点型:
浮点型表示只有两种,直接写小数或者科学计数法。如3.1415926、2.7e2(2.7×10^2)。
3.复数
j/J表示虚部,和数学中的一致。如1+2j
4.字符串
通常使用单引号,双引号以及三引号,单引号和双引号的字符序列必须在一行中,三引号的字符序列可以分布在连续的多行中。
注意:在字符串定界符引号的前面加上字幕r或R,那么该字符串可以按照原样输出,其中的转义字符将不转义。
5.布尔
很熟悉了不必多言1真0假,但要注意True和False的大小写情况。
运算符
主要区分两个点:
1.除法运算"/"在除不尽时将不再是C like的向下取整规则,而是以浮点形式表示。
2.比较关系运算符中可以形如“1<a<100”这样表示。
逻辑运算符中与或非分别是and or 和not
其他均保持不变。
分支与循环
一、分支
if…else
如果遇到二选一的条件,使用if else分支,其语法结构如下
if 表达式:
语句块1
else:
语句块2
流程图如下:
if…else语句还可简化,该简化形式与C++中的三目运算符相似以下面代码为例:
a = 1
if a > 0:
b = a
else:
b = -a
简写为
a = 1
b = a if a > 0 else -a
if…elif…else
elif相当于把else if缩写在了一起,该语句等同于C++中的if…else if…else,我们直接看流程图:
语法格式如下:
if 表达式1:
语句块1
elif 表达式2:
语句块2
elif 表达式3:
语句块3
...
else:
语句块 n
elif和else都必须和if一起使用,不能单独使用
if语句的嵌套:
注意:一定要严格控制缩进量
if 表达式1:
if 表达式2:
语句块1
else:
语句块2
else:
if 表达式 3:
语句块3
else:
语句块4
二、循环
1.while循环
while 表达式为真时执行:
循环体
流程图:
2.for循环
for 变量 in 对象:
循环体
对于for循环我们直接用流程图说明:
如输出1-100:
for i in range(101):
print(i)
range()函数也是Py的一个内置函数,它的作用是生成一系列的整数,其语法格式如下:
range(start,end,step)
- start:计数起始值,省略则从0开始。
- end:计数结束值(不包括本值),如range(3)表示0~2,不可省略!
- step:步长。
重点: 使用range()函数时,如果只有一个参数,那么表示指定的是 end值,如果是两个参数,则表示的是start和end,只有三个参数都在时步长才可以表示出来。
典例:输出10以内的所有奇数:
for i in range(1,10,2):
print(i,end = ' ')
输出结果:1 3 5 7 9
这里专门说明一下end= ’ '这个语句,它表明结束是以空格的方式结束,如果不加这个则默认为换行,输出结果如下:
1
3
5
7
9
遍历字符串:
如string= ‘我是一个字符串’
如果直接print(string),则会将其整个输出,我们也可以用for循环对其遍历输出:
string = '我是一个字符串'
for i in string:
print(i)
结合前面提到过的end,其输出结果:
我
是
一
个
字
符
串
横向输出而不空格:
for i in string:
print(i,end = '')
#结果
我是一个字符串
循环嵌套:原理完全一样,举一个例子:
while 表达式1:
while 表达式2:
循环体2
循环体1
其他for for嵌套,for while嵌套和其格式一样,把握好缩进即可。
三、跳转语句
1.break
遇到break即跳出循环
2.continue
遇到后跳出本次循环进行下一次循环
补充:pass空语句:占位置用的,没别的作用
例子:
for i in range(1,10):
if a == 5:
print(a)
else:
pass
#程序只会输出5
列表
Python 序列的基础操作
1.序列的索引
从左往右:0 1 2 3 4
从右往左:-1 -2 -3 -4
2.序列相加
Python中列表的功能相当强大,两个列表的拼接直接相加即可:
list1 = ["炒酸奶","红烧肉"]
list2 = ["鱼香肉丝","烤冷面"]
print(list1+list2)
得到结果:
['炒酸奶', '红烧肉', '鱼香肉丝', '烤冷面']
3.序列相乘
得到一个重复次数的列表:
list1 = ['Hello']
print(list1*3)
得到
['Hello', 'Hello', 'Hello']
4.元素检查
语法格式:
value in sequence
如果在列表中,则返回Ture,与之相对的是not in,若不在列表返回True,反之则False。
5.切片※
语法格式:
sname [start:end:step]
#start 为开始位置,不指定则默认0
#end 表示截止位置,不指定则默认为序列长度
#step 步长,不指定则连续访问
!易错点辨析!
如果是list1 = list2则该拷贝是一种浅拷贝,仅仅是一种指针形式由list1指向2,而将切片列表中省略只留[:],如:list3[:]表示复制整个名称为list3的序列。
列表的计算与应用
1.列表函数
- list() 将序列强制转化成列表
- str() 序列转换为字符串
- sum()求和
- sort(),sorted()排序,会重点说明。
- reversed()直接翻转列表
- enumerate()将序列组合为索引序列
list(data)举例
list(range(10,20,2))
得到列表
[10,12,14,16,18]
关于sort()和sorted(),先讨论sort()函数,其基本用法:
listname.sort(key= ,reverse= )
- listname.sort是排序函数的使用
- key提取关键字,比如key=str.lower表示在排序是不区分大小写,因为默认状态下对英文字符串排序先排大写再排小写,这与ASCII码有关
- reverse如果指定为True,则排序后会再翻转列表
sorted()在用法上与其完全一致,唯一不同点是sorted()会建立一个原列表的副本,该副本为排序后的列表,还是相当于深拷贝与浅拷贝的概念。
2.列表的访问
其访问形式类似于C++中的数组形式,如:
list1 = ["烤面筋","里脊扒饼","炸鲜奶"]
print(list1[2])
输出结果为
炸鲜奶
3.列表的遍历
① 直接使用for循环
list1 = ["烤面筋","里脊扒饼","炸鲜奶"]
for item in list1:
print(item)
② 使用for+enumerate()
使用组合可以同时输出索引值和元素内容
list1 = ["烤面筋","里脊扒饼","炸鲜奶"]
for index,item in enumerate(list1):
print(index+1,item)
输出:
1 烤面筋
2 里脊扒饼
3 炸鲜奶
4.列表元素的添加修改和删除
添加有三种方法:
- append() 列表末尾添加
- extend() 列表末尾添加一个列表,注意内部一定要加[ ]
- insert()某一元素前插入元素,执行效率较低不推荐使用。
修改元素直接赋值即可,删除元素使用del,如:
list1 = ["烤面筋","里脊扒饼","炸鲜奶"]
del list1[-1]
print(list1)
输出结果:
['烤面筋', '里脊扒饼']
如果要将一个不确定位置只确定元素值进行删除则使用remove()函数,要注意上面的del不是一个函数而是一条语句,它是索引式的删除。
list1 = ["烤面筋","里脊扒饼","炸鲜奶"]
list1.remove("炸鲜奶")
print(list1)
5.列表的统计计算
- count() 计数
- index()获取指定元素首次出现的位置
- sum()求和
6.列表推导式
语法格式:
listname = [Expression for var in LIST]
- Ex 计算表达式
- var 循环变量
- LIST 计算范围
筛选条件列表:
newlist = [Expression for var in list if condition]
元组
元组——tuple在形式上以()和,表示,在内容上任何类型的内容都可以放在一个元组中,通常元组用于保存程序中不可修改的内容,创建元组时直接赋值即可。
下列两种形式都是元组:
food = "水饺","灌汤包"
food = ("韩国炸鸡",)
下例则只是定义一个字符串:
food = ("韩国炸鸡")
在这里有一个和列表相同用法的转换方式:
tuple(data)
对符合元组的访问类似于C++中的二维数组形式:
food = ('abc',28,('炒酸奶','烤面筋'))
print(food[2])
('炒酸奶', '烤面筋')
print(food[2][0])
炒酸奶
print(food[2][1])
烤面筋
①元组元素的修改:
元组中的元素是无法直接修改的,但我们可以通过元组的重新赋值、连接组合进行修改,注意,元组只能和元组进行组合,除此之外的其他组合都会报错;数组连接时如果连接的数组只有一个元素一定不要忘记后面的逗号
②元组推导式:
与列表几乎完全一致,把[ ]改为()即可,但元组推导式的结果不是一个元组或列表,而是一个生成器对象,转换为元组使用tuple(),转换为列表则使用list()
字典
1.字典的创建和删除
dictionary = {'key1':'value1','key2':'value2',...,}
很容易想到字典的关键在于“键-值对”,“键”是索引,“值”即是键索引的内容。
引入创建字典的函数:dictionary = dir(zip(list1,list2)),list1做键,2做值,如果list1和list2的长度不同,则最后的结果长度与最短的一致,例:
name = ['张三','李四','王五']
age = ['19','20','18']
dictionary = dict(zip(name,age))#转换为字典,如果不用dict转换则其保持不可读的生成器模式
print(dictionary)
输出结果:
{'张三': '19', '李四': '20', '王五': '18'}
也可以通过给定的键值对创建字典
dictionary = dict(key1=value1,key2=value2,...,)
还可以使用函数fromkeys()创建只有键的空字典
name = ['张三','李四','王五']
dictionary = dir.fromkeys(name)
print(dictionary)
输出:
{'张三': None, '李四': None, '王五': None}
使用dictionary.clear删除字典元素。
2.字典的访问——键值对
判断访问的方法有两种:
- if判断处理
dictionary = {'张三': '19', '李四': '20', '王五': '18'}
print(dictionary['张三'] if '张三' in dictinoary else '字典无此人')
- get()指定获取
dictionary.get(key,[default])
3.字典的遍历
Python提供了items()函数用于字典的遍历:
for item in dictionary.items():
print(item)
这样得到的将是一个元组,若想获取各个具体的键和值,可以使用下列代码:
dictionary = {'张三': '19', '李四': '20', '王五': '18'}
for key,value in dictionary.items():
print(key,"的年龄是",value)
执行结果:
张三 的年龄是 19
李四 的年龄是 20
王五 的年龄是 18
Python还提供了values()和keys()方法专门获得值和键,用法与上述遍历一致。
4.添加、修改和删除字典元素
- 添加元素格式:
dictionary[key] = value #会添加到末尾
- 修改元素:
格式与添加的格式完全一致,只需给它直接赋新的value,当元素存在时即相当于修改功能
- 删除元素(这里直接介绍开发中最保险的方法——加入条件判断)
dictionary = {'张三': '19', '李四': '20', '王五': '18'}
if '李四' in dictionary:
del dictionary['张三']
print(dictionary)
5.字典推导式
推导式我们已经遇到了很多,字典推导式依旧和前面保持一致,直接上代码格式:
import random
randomdict = {i:random.randint(10,100) for i in range(1,5)} #创建字典
print(randomdict)
异常描述
这里我们列举一些常见的程序报错:
- ZeroDivisionError,0作为除数时的报错
- NameError 未声明变量引发的错误
- IndexError 索引超出序列范围
- IndentationError 缩进错误
- ValueError 传值错误
- KeyError 请求不存在的字典关键字
- IOError 输入输出错误
- ImportError import语句无法找到模块
- AttributeError 尝试访问未知对象属性
- TypeError 类型不合适
- MemoryError 内存不足
异常处理语句
1.try…except
try:
block1
except [ExceptionName [as alias]]:
block2
把可能出错的放在try后面,如果try后的语句报错则会执行except语句中的代码
[ExceptionName [as alias]] 是可选参数,用于指定要捕获的异常,ExceptionName则是异常名称,如果要加上as关键字,则表示为当前异常指定一个别名。
2.try…except…else
else用于当try后没有报错时执行,其他不变
3.try…except…finally
完整的异常处理语句应该包含finally模块,无论程序中有无异常产生,finally后的代码块都会执行,
4.raise抛出异常
raise [ExceptionName(reason)]
reason用于指定错误的描述信息,如果省略不写则原样抛出
5.assert
assert expression[,reason]
expression为assert语句的条件表达式,如果条件为假则抛出异常,该语句很常用,通常用于检测错误位置,reason是对错误的补充描述。
函数的创建与调用
使用def关键字,语法格式如下:
def function(形式参数):
['''用于调用时显示的注释''']
[函数体]
注意:在定义函数时也可以赋初始值,但是默认参数必须指向不可变对象。
调用语句:
function(实际参数)
- 形式参数:形参只是一种形式,他的作用是完成函数的运算法则,是一种占位呈现的作用。
- 实际参数:是函数在调用时真真正正传入的需要计算的值,而对于值运算的规则已经在函数定义时就用形参构造过了。
位置参数
顾名思义,位置参数需要按照正确的顺序传入到函数中,调用时的数量和位置必须与定义函数时保持一致。
关键字参数
关键字参数是使用形参的名字来确定输入的参数值,通过该方式指定实参时不再需要与形参的位置完全一致,参数名写对即可。
可变参数
1.*parameter
单星号表示接收任意多个实际参数并将其放在一个元组中,参数个数是可变的。
2.**parameter
双星号表示将其放到一个字典中,由于字典键值对的特性,因此接收时是显示赋值的实际参数
二者的区别就在于一个传参数一个传键值对,一个放到元组,一个放到字典
返回值
Python的return语句与C有些差别,语法格式:
result = return [value]
result用于保存返回结果,但是py中可以返回不止一个值,如果返回一个,则保存的就是一个值,如果是多个,保存的则是一个元组。 当然返回值可以是任何类型;如果没有return语句或者省略了其返回参数,则返回None,即空。
变量作用域
作用域方面与C语言极其相似。函数体内部定义的变量即为局部变量,整体定义的则为全局变量,当全局变量与局部变量重名时,对函数体内的变量赋值后,不影响函数体外的变量。
不同的是,py中可以在局部变量前加入global关键字将其声明为全局变量使用。
lambda
用的不多懒得起名字就用它…语法格式如下:
result = lambda [参数1,2,3,4......]:expression
result用于接收值,expression是对传入参数进行运算的表达式。举个例子:
定义一个计算圆面积的函数:
import math
r = 10
result = lambda r:math.pi*r*r
print(result(r))
需要新变量来接收这个值并以函数方式调用它;lambda主要用于指定短小的回调函数。
面向对象概述
1.对象
对象是一个抽象概念,表示任意存在的事物,万物皆对象。对象通常被划分为两个部分,静态部分和动态部分,静态部分被称为属性,动态对象被称为行为。
2.类
类是封装对象的属性和行为的载体,例如把某一事物比作其类,那么这个类自然就有了这个类中的全部属性,比如“人”类,该类中就具有胳膊腿嘴巴眼睛等属性,也有了学习看书谈恋爱睡觉等行为。
3.面向对象的特点
- 封装,将对象的属性和行为封装起来并隐藏实现细节
- 继承,子类从父类中得到父类所具有的一切
- 多态,子类不仅能从父类中继承一切,同时子类自身也会发展出属于自身的行为
类的定义和使用
1.类的定义
class ClassName:
'''帮助信息'''
statement #类体
2.创建类实例
将一个封装好的类通过“=”赋予一个实例名,并标全非self的参数即为创建:
Example = ClassName(可选参数)
3.创建__init__()方法
方法和函数的功能非常类似,在创建时也都是用def关键字,init()是Python中的默认方法,其括号中必须包含一个self参数,这个参数是指向实例本身的,例如:
class Fruit:
def __init__(self): #init方法创建
print("这是水果类的init方法创建")
apple = Fruit() #类的实例
当然还可以加入其它参数,逗号分隔开即可。前后双下划线是一种约定,将其与普通方法区分开。
4.创建类的成员并访问
创建实例方法,与init一样第一个参数必须是self,两者的使用几乎没有区别,语法格式如下:
def functionName(self,parameterlist):
block
parameterlist用于指定除了self以外的参数,各参数间逗号分隔
5.数据成员
- 类属性:定义在类中,并且在函数体外的属性,类属性可以通过类名或实例名访问
- 实例属性:定义在类的方法中的属性,只作用于当前实例,即在def函数模块内定义的。
注意:实例属性只能通过实例名访问。
6.访问限制
- foo:特殊定义方法,通常为系统定义名字,比如__init__()
- _foo:protected类型,只允许本身和子类访问
- __foo:private类型,只允许定义该方法的类本身进行访问,且不能通过类的实例进行访问。但可以通过"类的实例名.类名__xxx"方式访问。
属性
该属性与类属性和实例属性不同,他是一种特殊的抽象的属性
- 可以通过@property将一个方法转换为属性,从而实现计算,通过@property转换后的属性不能重新赋值。
- @property还可以为属性添加安全保护机制,在方法体前加@property实现只读属性,可以读取,不可修改。
继承
一个类可以从另一个类中继承其全部属性,就如我们都会从父辈继承一些性状一样,被继承的类称为父类或基类,新的类称为子类或派生类,Python继承语法如下:
class ClassName(要继承的基类名):
'''帮助信息'''
statement #类体
当基类中的某个方法不完全使用与子类时,就需要在子类中重写父类的此方法,重写格式与父类一样。
基类__init__()的调用
在派生类中定义该方法时,不会自动调用基类的该方法,如果调用则需要在其下方使用super()函数:
super().__init__() #调用基类的__init__()方法