基础语法
顺序语句
python在默认情况下指向代码的顺序是从上到下,每一行的语句再从左到右依次执行的,这个顺序是不会乱的:
print("111")
print("222")
print("333")
#输出结果是
#111
#222
#333
条件语句
也就是表达“如果···否则···”这样的语句,用 if else 关键字来表示条件语句,
- 用 “ : ”来判断的条件表示条件结束,
- if语句中要执行的代码块相对于C/java里面用 { } 来表示,python中使用缩进的方式来表示,这里指的的缩进通常是4个空格或者是1个tap。
ex = True
do1 = 0
do2 = 0
if ex:
do1 =1
do2 = 1
print(do1,do2)
#输出结果是 1 1
ex = False
do1 = 0
do2 = 0
if ex:
do1 =1
do2 = 1
print(do1,do2)
#输出结果 0 1
if - else:
ex = False
do1 = 0
do2 = 0
if ex:
do1 =1
else
do2 = 1
print(do1,do2)
#输出结果 0 1
if - elif - ········· - elif - else
python中的 else if 是表示成 elif的,其功能还是和 else if 一样的:
ex = False
ex1 = True
do1 = 0
do2 = 0
if ex:
do1 =1
elif ex1 :
do2 = 1
print(do1,do2)
例:实现让用户输入一个数字,如果输入1 表示愿意认真学习; 输入2表示摆烂:
put = input ("请输入一个数:")
put = int(put)
if put == 1:
print("快去学习")
elif put == 2:
print("摆烂吧")
#处理非法输入的情况
else:
print("输入错误")
输出结果:
缩进和代码块
在python中使用缩颈来表示代码块,不同级别的缩进,程序的执行效果是不同的。
左边的 print(“world”)不输入if里面的代码块,而右边的属于。
两个条件满足,打印hello,只满足a = “1”,打印world之后在打印python,都不满足就都不打印。
所以当有多级嵌套的时候,当前语句属于那个一个代码块,完全取决于缩进的级别。
但是这种利用缩进的方式来区分代码块,不容易理解代码,
例:
if a == 1:
if b == 2:
if c == 3:
if d == 4:
if e == 5:
if f == 6:
if g == 7:
print("hello")
print("1")
print("2")
这个就不如C/java等语言中用 { } 来区分代码块的方式更加简洁,但是我们在ptcharm中他会给我们用线条来提示:
但是,其他的python不保证有这种竖线来区分,所以我们在实际开发中还是要尽量避免写出这种嵌套关系这么复杂的代码!!确实可读性相对较差。
条件判断例子:
判断一个数是奇数还是偶数:
a = int (input("请输入一个整数:"))
if a % 2 == 1:
print("奇数")
else:
print("偶数")
需要注意的是:在C++/java 中 a % 2 == 1 这个是实现不了判断奇偶数的,因为在C++/java中 -19 % 2 = -1 ,而在python中,-19 % 2 = 1,所以在python中能实现。
空语句 pass
代码示例:输入一个数字,如果数字为1,则打印hello,反之:
a = int (input("请输入一个整数:"))
if a == 1:
print("hello")
这个代码等价于:
a = int (input("请输入一个整数:"))
if a == 1:
print("hello")
else:
pass
我们可以看到当输入的值不是1的时候就 “pass",但是一下的代码是还会报错的:
a = int (input("请输入一个整数:"))
if a == 1:
print("hello")
else:
会报一下错误:
也就是说,当我们写了if - elif - else之后代码块里一定要有内容,如果没有内容应该在这个代码块里写上 “pass”这条语句,表示这个代码块是空的,或者如果删除掉这个判断语句不影响程序执行逻辑的话,就像第一次代码一样,我直接不写这个else,不能删除就要使用“pass"来对这个代码块进行站位。
虽然先条件满足的时候啥都不做,但是由于python对于语法格式尤其是缩进和代码块要求较高,所以如果啥都不写(或者只写了注释)这种是不符合python的语法要求的。
在python中没有Switch这样的条件分支语句,因为python的设计理念就是解决一个问题只采用一种方案。
循环语句
while + 条件 :
循环体
- 条件为真,执行循环体;
- 条件为假,则结束循环;
例:
# 打印1-10 的整数
num = 1
while num <= 10:
print(num)
num += 1
输出结果:
1
2
3
4
5
6
7
8
9
10
while 循环 的 else 语句
通过使用 else 语句,当条件不再成立时,我们可以运行一次代码块:
i = 0
while i < 4:
print('hello world')
i += 1
else:
print('byebye world')
输出:
hello world
hello world
hello world
hello world
byebye world
我们发现,当 i = 4 的时候,while 循环条件不成立了,就会执行 else 里面的代码块。
for 循环变量 in 可迭代对象:
循环体
- python 中的 for 循环和其他语言不一样,没有“初始化语句”,“循环条件判断语句”,“循环变量更新语句”,而是更加简单
- 所谓的“可迭代对象”,指的是“内部包含多个元素,能一个一个把元素取出来的特殊变量”,这里的特殊变量,即列表,元组,字典,集合或字符串
例子:
#打印1-10的整数
for i in range(1,11):
print(i)
range是一个内建函数,起到的作用就是得到一个可迭代对象,这个可跌倒对象中就包含了一系列的整数,比如:
range(beg,end) => [beg,end)
这里的range函数就对应一块整数 -- -- -- 从beg开始到end结束,注意:这个区间是一个前闭后开的区间。
range还提供了第三个参数,这个参数表示步长,如果不输入这个步长,那么这个步长默认是“1”。
# 打印2 4 6 8 10 的整数
for i in range(2,12,2):
print(i)
如上:range(2,12,2)中的第二个2的位置就表示步长。接下来实现打印从10到1:
# 打印从10到1的整数
for i in range(10,0,-1):
print(i)
其中的range(10,0,-1)表示从10开始到0结束(不包含0),我们逆向走的时候步长为负数。
例:求 1 + 2 + 3 + ··· + 100
sum = 0
for i in range(1,101):
sum += i
print(f'sum = {sum}')
在pycharm中我们发现sum的下面有黄色的波浪线,这表示这个sum报了警告,报的警告如下:
这个警告的意思是当前我们python的内建函数里有一个内建函数 sum ,也就是说我们自己定义的变量和内建函数冲突了,虽然不影响代码运行,但是这个代码的后面就无法使用内建函数sum了。
解决办法就把这个sum换一个名字定义就行了。在pycharm中有一个快速修改变量名字的方法: 假设我现在要修改这个sum的名字,我就把光标放在这个sum变量的上面,然后按下 shift + F6,有些电脑是按shift + Fn + F6,就出现这个界面:
弹出这个界面之后这个rename就会自动识别我们要修改的变量名字,只需在第一空里也就是左图中sum所在的空格位置处,输出我们想要修改为的名字,然后点击Refactor这个选项就行了。
改完之后就是这个效果。
所有的sum位置的变量名都变成了thesum。
循环遍历字符串
甚至连字符串都是可迭代的对象,它们包含一系列的字符:
for x in "hello":
print(x)
#输出:
#h
#e
#l
#l
#o
For 循环中的 Else
for 循环中的 else
关键字指定循环结束时要执行的代码块:
for x in 'hello world':
print(x)
else:
print('\nbyebye world')
输出:
h
e
l
l
o
w
o
r
l
d
byebye world
我们发现,在for循环遍历打印完字符串 ‘hello world’ 的时候,还打印了 ‘byebye world’字符串。
break和continue
continue是立即结束当前这次循环,然后进入下一次循环
break是立即结束整个循环
这两个语句都是可以搭配while循环和for循环使用。
函数
函数是一段可以重复利用的代码:
定义一个函数:
#自定义一个函数
def calcsum(beg,end):
thesum = 0
for i in range(beg,end + 1):
thesum += i
print(thesum)
#调用函数
#求1-100的和
calcsum(1,100)
函数定义
- 形参列表中多个形参用逗号隔开
- 函数体和return返回值要有一行缩进
- return不是必须的,可以没有返回值
def 函数名(形参列表):
函数体
return 返回值
函数调用
#没有函数返回值时
函数名(实参列表)
#有函数返回值
返回值 = 函数名(实参列表)
注意:
- python中要求,函数定义写在前面,函数调用写在后面,也就是先定义在调用。
- 相对于C++/java里自定义函数里的形参和调用函数里的实参,这两个参数的类型是需要一一匹配的,每一个位置对应的参数类型必须一致,但是在python中,只是要求形参和实参的个数必须一致,但是每一个位置的参数的类型没有要求(动态类型)。
- 但是不是不管类型就可以随意的传入啥类型都可以,我们传入的参数类型得保证这个函数里的函数体能实现这个函数所要实现的功能才行。
def test(a):
print(a)
test(10)
test('hello')
test(True)
运行结果:
函数的返回值
函数的参数可以视为函数的“输入”,那么函数的返回值可以视为是函数的“输出”,return返回值可以在函数体总可以写多个,但是在执行到return的时候,这个函数就会执行结束并返回这个值。
def isOdd(num):
if num % 2 == 0:
return False
else:
return True
def isOdd(num):
if num % 2 == 0:
return False
return True
需要注意的是:相对于C++/java我们的python中的一个函数可以返回多个值,把需要返回的值用逗号隔开就行了。
def getPoint():
x = 10
y = 20
z = 30
return x,y,z
既然返回了多个值,那么我们接受这个函数的返回值的时候就用 多元赋值 来接收就行了,如上面这个函数举例子:
def getPoint():
x = 10
y = 20
z = 30
return x,y,z
a,b,c = getPoint()
此时的a, b ,c 分别等于 10 20 30;
我们还可以值接收部分的函数返回值:
def getPoint():
x = 10
y = 20
z = 30
return x,y,z
_,b,c = getPoint()
我们使用 _ 来把不需要接收的值给跳过,然后把需要接收的值用变量接收。
注意:
- 在函数里尝试读取全局变量是可以的,当函数中尝试访问某个变量的时候,会先尝试在局部变量中查找没如果找到,就直接反问,如果没有找到,就会往上一级作用域中进行查找,如上getPoint函数在往上寻找就是全局了。
- python中:在所有函数定义之外的变量称为全局变量,而在函数内部定义的变量或者是代码块里的变量称为局部变量
函数的执行过程
首先我们来看一个例子:
def test():
print("执行函数体的内容")
print("执行函数体的内容")
print("执行函数体的内容")
print("1111111")
test()
print("2222222")
test()
print("3333333")
test()
print("4444444")
执行结果:
我们发现虽然python的执行顺序是从上到下,再在每一行从左到右执行,但是我们在 def 定义一个函数的时候,函数体的部分它并不会执行,之后在后面调用函数的之后再执行函数的内容,这时因为前面 def 函数只是定义函数并不会执行函数体里面的内容。
pycharm可以支持我们进行调试操作,我们在代码左边的空列处左键点击一下就可以设置断点:
设置完断点之后就可以右键代码点击Debug进行调试操作:
记住一定要先设置断点在Debug运行,不然会像 run 一样直接把代码运行完,在我们debug之后,就会出现下面这一个窗口:
他是debug的输出窗口,我们在最下面一行可以切换窗口;最上面有蓝色箭头的是我们调试过程中可以进行的操作:
这个操作是单步运行,并且遇到我们自定义的函数他可以跳到函数里面去。
这个页面显示的是函数的调用栈,描述了当前的代码是怎么跳转过去的(进一步的也就是函数之间的调用关系) 其中这个图的两行代码意思是从bite这个文件里面的第8行代码,进入到了bite文件里面的第2行代码。
函数的链式调用
用一个函数的返回值作为另一个函数的参数
def isOdd(num):
if num % 2 == 0:
return False
return True
def add(x,y):
return x + y
print(isOdd(add(5 + 5))) #链式调用isOdd add print
链式调用中,实现执行()里面的函数,后执行外面的函数,也就是说,调用函数的时候,要先把他的参数给求出来。
函数的嵌套调用
一个函数体内部也可以调用其它函数
def a():
print('函数 a')
def b():
print('函数 b')
a()
def c():
print('函数 c')
b()
c()
运行结果:
函数 c
函数 b
函数 a
函数的递归
#求10的阶乘
def factor(n):
if n == 1:
return 1
return n * factor(n - 1)
factor(10)
函数形参的默认值
在python中的函数,可以给形参指定默认值
带有默认值的参数,可以在调用的时候不传参。
例:
def add(x , y , debug):
if debug:
print(f'x = {x},y = {y}')
return x + y
result = add(10, 20, True)
print(result)
当我们在调用函数的时候第三个参数传的是True就会打印 x y 的值,False 就不打印。如下:
其实这个函数可以这样写:
我们在调用的时候如果不传这个debug的值,那么这个debug的值默认是False,如果传入了值那么debug的值就是传入的那个值。
注意:我们一般把这个带有默认值的形参,放在形参列表的后面,而不能在中间,如果吧有默认值的放在中间就会报错:
当有多个默认参数的形参的时候,所有的这些形参都得放在后面。
关键字参数
我们函数的传参除了如上图一样的实参对应位置传参给形参之外,还可以进行关键字传参:
那么什么事关键字传参?关键字传参就是按照形参的名字来进行传参,例:
def test(x, y):
print(f'x = {x}')
print(f'y = {y}')
test(x=10, y=20)
在我们调用的test函数的时候,相比于 test(10 , 20) ,我们多加了一个 x = 10 和 y = 20 ,这样来传参,而这里的 x 和 y 来源于我们在定义test函数的时候定义的形参名字,也就是说我们在用关键字进行传参的时候,他不像之前的位置传参一样需要对于位置进行传参,只需要写:
形参名 = 数据
这样就行了,当然此时传参的顺序是无关的:
def test(x, y):
print(f'x = {x}')
print(f'y = {y}')
test(y = 100 , x = 20)
这样写也是没有问题的。
而且这个位置参数和关键字参数还可以混着用,只不过混着用的时候要去位置参数在前面,关键字参数在后面。
一个函数可以提供很多的参数,来实现对这个函数内部功能做出一些调整设定;为了降低调用函数的人的使用成本,就可以把多部分的参数设定出默认值!当调用者需要调整其中的一部分参数的时候,就可以搭配关键字参数进行操作。
任意参数
如果您不知道将传递给您的函数多少个参数,请在函数定义的参数名称前添加 *。
这样,函数将接收一个参数元组,并可以相应地访问各项:
def function(*num):
print(num)
function('hello','world','byebye')
输出:
('hello', 'world', 'byebye')
由此可以看出,我们的num 的形参 是以元祖的方式来 接收我们 传入的实参数据的。
既然是元祖,那么我们需要取出我们传入的参数的时候就可以用 [ ] 的方式来进行访问:
def function(*num):
print(num[0])
print(num[2])
function('hello','world','byebye')
输出:
hello
byebye
pass 语句
我们自定义的函数的代码块里面,不能为空,如果我们在定义函数的时候,里面的内容为空就会报错:
def function(*num):
function('hello','world','byebye')
这个时候,我们要在代码块里面加一个 pass 语句,就可以避免这样的报错:
def function(*num):
pass
function('hello','world','byebye')
函数里的函数
我们知道函数的调用,编译器是要创建函数指针的,这就使得函数里的变量为局部变量,函数就不能使用了,但是只要是在函数内部,这个局部变量都是可以使用的:
def Func1():
num = 100;
def Func2():
print(num)
Func2()
return
print('调用函数')
Func1()
输出:
调用函数
100
不在函数内部定义的变量都是全局变量,是在这个程序定义了这个变量之后,这个变量在之后的代码中都可以任意使用。
global 关键字
如果我们在函数内部定义的局部变量,我们想要它在全局的作用域之内都可以作用到,这个时候是用 global 关键字就可以把这个局部变量变成全局变量。
def Func1():
global num
num = 100
return
Func1()
print(num) #100
需要注意的是:这个 Func1 函数中的 num 变量 必须先用 global 关键字声明之后,才能在进行赋值,如果声明和赋值一起进行就会报错:
def Func1():
global num = 100
return
Func1()
print(num)
编译器告诉我 这是一个无效的语法。
另外,如果我们需要在函数内部修改全局变量 ,那么在修改之前就要使用 global这个关键字声明之后再去才能取修改:
num = 200
def Func1():
global num
num = 100
return
Func1()
print(num) #100
如果不声明 就去修改全局变量的话 :
num = 200
def Func1():
num = 100
return
Func1()
print(num) #200
我们发现 num 变量的值还是输出为 200 , 并没有被修改为 100。
lambda 函数
lambda 函数是一种很小的匿名函数,也就是说:函数没有具体的名称。
语法:
lambda [arg1 [,arg2,.....argn]]:expression
argn : 指的是我们需要传入的参数
expression : 指的是表达式,注:这个表达式只能有一个
lambda函数的返回值是:这个表达式的值
sum = lambda x,y,z : x + y + z
print(sum(1,2,3))
我们用一个sum变量来接收这个lambda 函数的返回值,那么这个 lambda 函数里面的参数我们可以在sum 变量里面 用 sum(arg1,arg2,········,argn)这样的方式进行传参。
但是其实这个lambda 匿名函数其实没有多大用处,因为这个函数实现的功能基本都能通过其他的代码来实现。
这个lambda 函数的功能主要实现在,自定义函数里面的使用:
如果我们在我们自定义函数中使用这个lambda匿名函数,就可以感受到他的功能强大。
def Func(n):
return lambda a : a * n
ret = Func(3)
print(ret(22)) # 输出: 66
Func(3) 中的 3 是给Func中的 n 这个形参传参;而 我们在print()函数中的 ret(22) 是给Func()函数中的 lambda 的 a 参数传参。
由此我们可以用一个 def 自定义函数写出很多个 类型的 def 自定义函数了:
def Func(n):
return lambda a : a * n
ret1 = Func(3)
ret2 = Func(4)
print(ret1(22)) # 输出: 66
print(ret2(22)) # 输出: 88
我们发现,这个时候在同一程序中使用相同的函数定义来生成两个函数。