##判断与循环
##判断语句if
##单分支
if 条件:
代码块
1.冒号必须是英文状态下
2.必须要缩进
##流程
eval(字符串)
1.把字符串转换成int类型
a = eval("10")
print(a) #10
print(type(a)) #<class 'int'>
2.对字符串进行计算
a = "3*2"
print(a) #3*2
b = eval(a)
print(b) #6
"""
#input("请猜一个数字") ---Str
#eval() 把Str转换成int
guess = eval(input("请猜一个数字"))
if guess ==99:
print("恭喜你猜对了") #恭喜你猜对了
##二分支
if 条件:
代码块
else:
代码块
##流程
guess = eval(input("请猜一个数字"))
if guess == 99:
print("恭喜你猜对了")
else:
print("谢谢惠顾")
##多分支
if 条件:
代码块
elif 条件:
代码块
elif 条件:
代码块
else:
代码块
##流程
score = eval(input("请输入一个成绩:"))
if score >= 90:
print("a")
elif 90 > score>=80:
print("B")
elif 80 >score>=70:
print("C")
elif 70>score>=60:
print("D")
else:
print("不及格")
##三目运算符 满足条件的代码块 if 条件 else 不满足条件的代码块
##流程
print("恭喜你,猜对了")if guess == 99 else print("谢谢惠顾")
##条件判断以及组合
操作符 | 数学符号 | 描述 |
< | < | 小于 |
<= | ≤ | 小于等于 |
>= | ≥ | 大于等于 |
> | > | 大于 |
== | = | 等于 |
!= | ≠ | 不等于 |
操作符及使用 | 描述 |
x and y | 两个条件x和y的逻辑与 |
x or y | 两个条件x和y的逻辑或 |
not x | 条件x的逻辑非 |
##循环
目标程序的三大流程
1.while 循环的基本使用
2.break 和 continue
3.while 循环嵌套
在程序开发中,一共有三种流程方式:
顺序:从上向下,顺序执行代码
分支:根据条件判断,决定执行代码的分支
循环:让特定代码重复执行(解决程序员重复工作)
1.遍历循环:for 语句
根据循环执行次数的确定性,循环可以分为确定次数循环和非确定次数循环。确定次数循环指循环体对循环次数有明确的定义循环次数采用遍历结构中元素个数来体现。
-
for <循环变量> in <遍历结构>:
-
<语句块>
( 1)计数循环(N次)
for i in range(N):
<语句块>
(2)计数循环(特定次)
for i in range(N,M,K):
<语句块>
遍历由range()函数产生的数字序列,产生循环
(其中range()的用法和String的用法一样)
for i in range(1,6):
print("hello:",i)
print("*****************")
for j in range(1,6,2):
print("hello:",j)
(3)字符串遍历循环
for c in s :
<语句块>
for c in "python":
print(c,end=",")
注:end表示不换行,为末尾end加一个end=“”双引号里面的字符串
(4)列表遍历循环
-
for item in ls:
-
<语句块>
--ls是一个列表,遍历某每个元素,产生循环
for item in [123,"python",456]:
print(item,end=",")
2. 无限循环:while语句
无限循环:
无限循环一直保持循环操作直到特定循环条件不被满足才结束,不需要提前知道确定循环次数。
Python通过保留字while实现无限循环,使用方法如下:
while <条件>:
<语句块>语句块
a=5
while a>0:
print(a)
a=a-1
a=5
while a>0:
print(a)
a=a+1
这种结果是一直在执行
3. 循环保留字
循环结构有两个辅助保留字:break和continue,它们用来辅助控制循环执行
break用来跳出最内层for或while循环,脱离该循环后程序从循环后代吗继续续执行
其中,break语句跳出了最内层for循环,但仍然继续执行外层循环。每个break语句只有能力跳出当前层次循环
for s in "python":
for i in range(5):
print(s,end="")
if s=="t":
break
结果:pppppyyyyytooooonnnnn
- continue用来结束当前当次循环,即跳出循环体中下面尚未执行的语句,但不跳出当前循环。
- 对于while循环,继续求解循环条件。而对于for循环,程序流程接着遍历循环列表
for s in "python":
if s=="t":
continue
print(s,end="")
结果:python
or s in "python":
if s=="t":
break
print(s,end="")
结果:py
continue语句和break语句的区别是:
- continue语句只结束本次循环,而不终止整个循环的执行。
- break语句则是结束当前最内层循环过程,不再判断执行循环的条件是否成立
##函数进阶
##参数传递机制
函数参数传递机制和赋值机制是一样的,其本质就是传递内
存地址,这就是引用传递
a传进来的时候传进来的是内存地址
如果实在不理解,你可以以为是 x= a
def isid(x):
#打印参数的内存地址
print(id(x))
a = 10
#变量的内存地址
print(id(a)) #140731588047408
#a变成的参数,打印参数内存地址
isid(a) #140731588047408
默认参数
#定义一个带有默认参数的函数
def add(x,y=10):
sum01 = x+y
return sum01
"""
1.add(2) x=2 y=10
2.add(2,3) x=2 y=3
"""
print(add(2)) #12
print(add(2,3)) #5
能不能传参传入一个序列类型,比如list,让他默认是[]
def add(list01 = []):
list01.append(1)
return list01
#第一调用
print(add()) #[1]
#第二次调用
print(add()) #[1, 1]
#第三次调用
print(add()) #[1, 1, 1]
##不定数目的参数
##一个 *
def add(x,*y):
sum01 = x
for i in y:
sum01 += i
return sum01
print(add(1,2,3,4,5)) #15
##两个*
**y代表可以使用任意 键值(字典) 作为参数
**y就相当于字典类型
def func_add(x,**y):
sum01 = x
#切记这里是字典的循环
for k,v in y.items():
print(k,v)
#把v(值)进行和x相加
sum01 += v
return sum01
调用
a=3,b=4,c=5 ----> {"a":3,"b":4,"c":5}
print(func_add(1,a=3,b=4,c=5)) #13
##高阶函数
高阶函数是一个( 以函数为参数,或者以函数为返回值的)函数
函数可以是参数,参数是变量,那么函数可以是变量吗
参数其实就是变量进行了赋值,函数能不能是变量
函数为变量(补充)
函数为变量并不是高阶函数,只是和大家补充这个知识点
def func_pf(x):
return pow(x,2)
#字典
#已知李四的年龄是5的平方,求李四的年龄
dict01 = {"张三":20,"李四":func_pf}
"""
调用
1.func_pf = dict01["李四"] 根据key获取value,vaule是一个函数对象
2.age02 = func_pf(5) #调用函数就能获取年龄
"""
#字典的特点是根据key获取value
age01 = dict01["张三"]
print(age01) #20
#顾名思义,通过李四,我们可以拿到函数func_pf
#拿到的是函数对象,我们不能直接打印
func_pf = dict01["李四"]
print(func_pf) #<function func_pf at 0x000001E25A23D048>
age02 = func_pf(5)
print(age02) #25
## 函数为参数
#普通函数
def func_pf(x):
return x**2
#高阶函数,以函数为参数
def func_add(func_pf):
#x**2+10
return func_pf+10
#2**2+10
a = func_add(func_pf(2))
print(a) #14
##常用的高阶函数
map(fun,x) 转换,接受一个序列,按照fun的函数逻辑转换成新的序列,返回一个map对象
- x必须是一个序列
- 返回一个map对象
def func_add(x):
return x+1
"""
把原来的数据,经过func_add函数以后,每一个都加1,然后输出新的列表
"""
m = map(func_add,[1,2,3,4,5])
print(m) #<map object at 0x00000248E965C788>
print(list(m)) #[2, 3, 4, 5, 6]
##filter()
filter(func,x) 过滤,接受一个序列x,按照func函数要求进行转换,
func函数返回 True 或 False,最后将返回 True 的元素放到新列表中。
返回filter对象
ilter(func,x) 过滤,接受一个序列x,按照func函数要求进行转换,
func函数返回 True 或 False,最后将返回 True 的元素放到新列表中。
返回filter对象
"""
def func_ifScore(x):
#比较运算符,本身就是返回布尔值的
#如果大于等于60就是Ture,否则就是False
return x>=60
f = filter(func_ifScore,[80,98,70,34,60,59,10])
print(f) #<filter object at 0x00000232CC78C808>
print(list(f)) #[80, 98, 70, 60]
##reduce()
reduce(func,x) 计算,接受一个序列,把列表中的每一个值按照函数进行累加或者别的运算
返回一个计算数值
1.因为是计算,所以我们的func是两个参数
2.必须要导包
def func_add(x,y):
return x+y
a = reduce(func_add,[1,2,3,4,5])
print(a) #15
## lambda表达式
lambda表达式是一行函数。在其他语言中叫做匿名函数
语法:lambda 参数1,参数2,参数n : 逻辑
def func01(x,y):
return x**y
lambda x,y:x**y
##函数的递归
递归是指函数在执行过程中调用了本身。简单来说就是自己调用了自己
1.自己调用自己
2.一定要有一个条件,进行退出调用
阶乘:
比如说给一个数据5,阶乘5*4*3*2*1
n = 5*(5-1)
n =n*(4-1)
n =n*(3-1)
n =n*(2-1)
总结规律
n! = n*(n-1)
"""
def func_jc(n):
if n==1:
return 1
else:
return n*func_jc(n-1)
print(func_jc(5)) #120
## 装饰器
装饰器是一个函数
2.装饰器是一个 为函数添加新的属性 的函数
3.通过闭包对函数添加新的属性
def zhuangxiudui(a):
#闭包函数
def zhuangxiufangan():
print("贴瓷砖")
a()
print("隔音棉")
return zhuangxiufangan
@zhuangxiudui
def qiang():
print("来看看,就是这三面强")
#16-18行相当于 zhangxiudui(qiang)
#把qiang作为参数,传给了装修队这个函数
@zhuangxiudui
def men():
print("我是门")
"""
22-24行代表 zhangxiudui(men)
"""
#一周之后我来验货,来看看强弄好了没
qiang()
"""
贴瓷砖
来看看,就是这三面强
隔音棉
"""
一、global
global关键字用来在函数或其他局部作用域中使用全局变量。
1.1 如果局部要对全局变量修改,而不使用global关键字。
count = 0
def global_test():
count += 1
print(count)
global_test()
会出现如下错误:
1.2 如果局部要对全局变量修改,应在局部声明该全局变量。
count = 0
def global_test():
global count
count += 1
print(count)
global_test()
输出1
global将局部变量(函数内部)变成了全局变量(整段代码任何位置都可以使用),在某些情况下可以有更好的效果(但大多数都不是)
所以要尽量避免使用全局变量
##ruturn
return语句就是把执行结果返回到调用的地方,并把程序的控制权一起返回
程序运行到所遇到的第一个return即返回(退出def块),不会再运行第二个return。
例如:
def haha(x,y):
if x==y:
return x,y
print(haha(1,1))
已改正:
结果:这种return传参会返回元组(1, 1)
但是也并不意味着一个函数体中只能有一个return 语句,例如:
def test_return(x):
if x > 0:
return x
else:
return 0
print(test_return(2))
函数没有 return,默认 return一个 None 对象。
递归函数中没有return 的情况:
def recurve(a,b):
if a%b==0:
return b
else:
gcd(b,a%b)
分析:else 中没有 return 就没有出口,这个程序是自己内部运行,程序没有返回值,
5、默认情况下,遇见 return 函数就会返回给调用者,但是 try,finally情况除外:
def func():
try:
print(666)
return 'ok'
finally:
print(666)
print(func())
##迭代器
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一 个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
可迭代对象
以直接作用于 for 循环的数据类型有以下几种:
一类是集合数据类型,如 list 、 tuple 、 dict 、 set 、 str 等;
一类是 generator ,包括生成器和带 yield 的generator function。这些可以直接作用于 for 循环的对象统称为可迭代对象:Iterable 。
判断是否是可迭代
可以使用 isinstance() 判断一个对象是否是 Iterable 对象:
可以使用 isinstance() 判断一个对象是否是 Iterable 对象:
1.with语句
我们经常看到with open(xxxx,xxxx) as f这样的语句打开文件,但是却不用关闭,实际上它会自动调用了上下文管理器的上下文方法。当使用with语句时会调用上文方法__enter__(),with语句结束时会自动调用下文方法 __exit__() 进行关闭
使用语法:with 上下文管理器对象 as 上文函数执行的返回资源:
2.演示(打开文件)
我们一般用open()函数打开一个文件,现在我们定义一个类来演示上下文被调用
class File(object):
def __init__(self, file_name, mode):
self.file_name = file_name
self.mode = mode
# 调用上文
def __enter__(self):
print('执行上文')
self.file = open(self.file_name, self.mode)
return self.file # 返回的内容,即with语句后的as指向的内容
# 调用下文
def __exit__(self, exc_type, exc_val, exc_tb):
print('执行下文')
self.file.close()
if __name__ == '__main__':
with File('test.txt', 'r') as file:
data = file.read()
print(data)
***
结果:
执行上文
good morning(读取到的test.txt的内容)
执行下文
***
3.演示(数据库)
import pymysql
class SQL(object):
def __init__(self, host, user, password, database):
self.host = host
self.user = user
self.password = password
self.database = database
def __enter__(self):
print('执行上文')
self.__conn = pymysql.connect(host=self.host, port=3306, user=self.user, password=self.password,
database=self.database, charset='utf8')
self.__cs = self.__conn.cursor()
return self.__cs
def __exit__(self, exc_type, exc_val, exc_tb):
print('执行下文')
if exc_type:
self.__conn.rollback()
print(exc_val)
else:
self.__conn.commit()
self.__cs.close()
self.__conn.close()
return True
if __name__ == '__main__':
with SQL('localhost', 'root', 'mysql', 'jing_dong') as cs:
row_num = cs.execute('select * from goods')
if row_num > 0:
for i in cs.fetchall():
print(i)
##变量作用域
一、局部变量
我们最先是在main函数内部定义了一些变量并使用它们,例如:
int main(int argc, char *argv[])
{
int a;
int b;
int c;
//do something
return 0;
}
像这样在函数(并非只有main函数,所有函数都一样内部的变量被称为局部变量,它们的作用域就是当前函数内部。也就是说,这些变量只能在其内部使用,而不能在函数外部使用。
二、全局变量 与局部变量相对的就是全局变量,我们把定义在函数外部的变量称为全局变量,这些变量的作用域为整个程序,也就是说所有的函数和结构化语句都可以使用他们,
/* a.c */
int a;
int b;
int afunc(void)
{
a = 2;
b = a;
//do somethine
return 0;
}
##异常处理
一.异常简介
- 异常是指在语法正确的前提下,程序运行时报错就是异常。
- 当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
print ('-----test--1---')
open('123.txt', 'r')
print ('-----test--2---')
-----test--1---
Traceback (most recent call last):
File "D:/Phython/study/venv/Include/hello.py", line 2, in <module>
open('123.txt', 'r')
FileNotFoundError: [Errno 2] No such file or directory: '123.txt'
Why?-->
打开一个不存在的文件123.txt,当找不到123.txt 文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:123.txt (没有123.txt这样的文件或目录)
一、try:except:用法
程序正常运行,则执行try里面的代码,程序异常,则执行except里面的代码,except可捕获多个具体异常。
# 例如
number = 20
a = [-4, -2, 0, 2, 4]
for i in range(len(a)):
try:
result = number/a[i] # 分母为0时,抛出异常
print(result)
except Exception as e: # 所有的普通异常都包含在Exception里面
print("出错啦!", e)
运行结果
更加丰富的结构
# 例如
try:
print("我是尝试运行")
except NameError: # 捕获具体异常
print("命名错误!")
except ZeroDivisionError:
print("分母不能为0")
else:
print("我是try执行完后,执行")
finally:
print("无论如何,我最终都会执行")
- except捕获多个异常
try:
print (num)
except IOError:
print('产生错误了')
产生错误了
#coding=utf-8
try:
print('-----test--1---')
open('123.txt','r') # 如果123.txt文件不存在,那么会产生 IOError 异常
print('-----test--2---')
print(num)# 如果num变量没有定义,那么会产生 NameError 异常
except (IOError,NameError):
#如果想通过一次except捕获到多个异常可以用一个元组的方式
print("捕捉到异常")
-----test--1---
捕捉到异常
- try…finally…
- 在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally。比如文件关闭,释放锁,把数据库连接返还给连接池等。
import time
try:
f = open('test.txt')
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except:
#如果在读取文件的过程中,产生了异常,那么就会捕获到
#比如 按下了 ctrl+c
print("捕捉到异常")
finally:
f.close()
print('关闭文件')
except:
print("没有这个文件")
test.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl+c中断(取消)程序。
我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关
##三.异常的传递
- try嵌套中
-
import time try: f = open('test.txt') try: while True: content = f.readline() if len(content) == 0: break time.sleep(2) print(content) finally: f.close() print('关闭文件') except: print("没有这个文件")
- 函数嵌套调用中
-
def test1(): print("----test1-1----") print(num) print("----test1-2----") def test2(): print("----test2-1----") test1() print("----test2-2----") def test3(): try: print("----test3-1----") test1() print("----test3-2----") except Exception as result: print("捕获到了异常,信息是:%s" % result) print("----test3-2----") test3() print("------华丽的分割线-----") test2()
----test3-1----
----test1-1----
捕获到了异常,信息是:name 'num' is not defined
----test3-2----
------华丽的分割线-----
----test2-1----
----test1-1----
Traceback (most recent call last):
File "D:/Phython/study/venv/Include/hello.py", line 26, in <module>
test2()
File "D:/Phython/study/venv/Include/hello.py", line 9, in test2
test1()
File "D:/Phython/study/venv/Include/hello.py", line 3, in test1
print(num)
NameError: name 'num' is not defined
四.抛出自定义的异常
- 你可以用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类
下面是一个引发异常的例子:
-
class ShortInputException(Exception): '''自定义的异常类''' def __init__(self, length, atleast): #super().__init__() self.length = length self.atleast = atleast def main(): try: s = input('请输入 --> ') if len(s) < 3: # raise引发一个你定义的异常 raise ShortInputException(len(s), 3) except ShortInputException as result:#x这个变量被绑定到了错误的实例 print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.atleast)) else: print('没有异常发生.') main()
情况1
请输入 --> hello
没有异常发生.
情况2
请输入 --> la
ShortInputException: 输入的长度是 2,长度至少应是 3