路飞学城-Python开发集训-第3章
学习心得:
通过这一章的作业,使我对正则表达式的使用直接提升了一个level,虽然作业完成的不怎么样,重复代码有点多,但是收获还是非常大的,有点找到写代码的感觉了,遗憾的是,这次作业交过,这次集训就结束了,后面视频中的作业和内容将不再做讲解,也没有作业批改,不论如何这次集训对于自己提升还是蛮多的,真的要感谢路飞这个学习平台。
学习笔记:
三元运算:
三元运算又称三目运算,是对简单的条件语句的简写。
#简单条件语句
if 条件成立:
val=1
else:
val=2 #改成三元运算
val=1 if 条件成立 else 2
小例子:
a = 2
b = 5
val = a if a <b else b
print(a)
函数:
函数的参数类型:位置参数、关键字参数、缺省参数、非固定参数
*args
def send_alert(msg,*args,age):
for u in args:
print("报警发送给",u) #如果参数中出现 *agrs,传递的参数就可以不再是固定个数,传过来的所有参数打包成元组
#传参数有两种方式,一种是方式一,这种情况下所有参数被打包成元组
#另一种方式是方式二,直接传一个元组或列表,注意一定要在元组或列表前面加*,不然会把他们当成一个参数
#其实本质就是args就是一个元组
#一般情况下非固定参数放在最后,后面不加其它参数,这里后面加个age是为了实验效果,由于args会截获所有位置参数,所以这里在给age传参数的时候,必须要指明,不然也会被args截获,从而没有age的错 #方式一:
send_alert("别再浪了","alex","eric","rain",age=22) #方式二:
send_alert("别再浪了",*["alex","eric","rain"],age=22)
**kwargs
def func(name,*args,**kwargs):
print(name,args,kwargs) func("alex") #alex () {} 可以看出后面两个参数是可以不传的,不传就为空 func("alex",22,"tesla","500w",addr="山东",num=1244) #alex (22, 'tesla', '500w') {'addr': '山东', 'num': 1244}
#args会截获位置参数,而kwargs会截获关键字参数 d={"degress":"primary school"}
func("peiqi",d) #peiqi ({'degress': 'primary school'},) {}
func("peiqi",**d) #peiqi () {'degress': 'primary school'} 这个和上面args一样的道理
局部变量:
(1)局部变量和全局变量在某种程度上是两个独立的空间,相同的变量名代表不同的变量,所以局部并没有修改全局变量,而是在局部创建一个相同变量名的变量。
name="black girl" def change_name():
name="黑色的女孩"
print(name) change_name() #黑色的女孩
print(name) #black girl
(2)查找变量遵循从自身开始按LEGB方向查找,比如在全局调用变量,那么就从身G开始,按GB方向查找,不会往后找。
(3)由于局部变量和全局变量是两个独立空间,那如果想在局部修改(重新赋值方式)全局的变量,怎么办?
name="black girl" def change_name():
global name #声明name是全局的那个变量,声明要放在变量前面,不然会报错!在生产环境中不建议在局部修改全局变量
name="黑色的女孩"
print(name) change_name() #黑色的女孩
print(name) #黑色的女孩
注意下面这种方法虽然能修改变量的值,但其实并没有修改变量本身,变量并没有变。
name=["alex","black girl","peiqi"] def change_name():
global name
del name[2]
print(name) change_name() #['alex', 'black girl']
print(name) #['alex', 'black girl']
变量自身有没有变可以看内存地址,如果内存地址变了,说明这个变量变了
name=1
print(id(name)) #
name=2
print(id(name)) # name=["alex","black girl","peiqi"]
print(id(name)) #
del name[2]
print(id(name)) #
嵌套函数:
#情形一
def func1():
print("alex")
def func2():
print("eric")
func1() #alex
#分析:为什么结果只打印了一个alex,而没有打印eric?
#这是因为函数定义的时候不会被执行,如果想执行必须调用,题中调用了函数1,而函数1在执行的时候先是打印了alex,
# 然后定义了函数2,但这只是定义了函数2,并没有执行,所以只打印了alex #情形二
def func1():
print("alex")
def func2():
print("eric")
func2()
func1() #alex eric
#分析:为什么这次两个都打印了?
#这是因为在执行函数1时,先打印了alex,然后定义了fun2,定义函数2之后,又执行了函数2,所以两个都打印了。 #情形三
age = 19
def func1():
age =73
print(age)
def func2():
age = 84
print(age)
func2()
func1() #73 84
#这个没什么好说的。 #情形四
age = 19
def func1():
age =73
print(age)
def func2():
print(age)
func2()
func1() #73 73
#这个也没什么好说的,按照LEGB的原则去找,fun2在自己内部找不到age变量,就到它的父级去找,在父级找到了就打印了 #情形五
age = 19
def func1():
def func2():
print(age)
age = 73
func2()
func1() #
#由于定义age是在执行func2之前,所以age存在于他的父级作用域,所以它就在父级作用域找到了age,所以打印了73 #情形六
age = 19
def func1():
def func2():
print(age)
func2()
age = 73
func1() #报错:NameError: free variable 'age' referenced before assignment in enclosing scope
#分析:为什么会报错?
#虽然父级作用域存在age变量,但func2在调用的时候age还没有被定义,这就出现了调用在定义之前,所以报错,这个和global那个比较类似 #情形七
age = 19
def func1():
global age
def func2():
print(age)
func2()
age = 73
func1() #
print(age) #
#这个global声明是在最上面的,所以fun2在自身没找到后,往父级找,其实在父级也没找到(父级中的age也是全局的,只是在局部被重新赋值了),
# 然后往global找,找到了age=19,所以就打印了。打印73是因为被重新赋值导致的 # 情形八
age = 19
def func1():
global age
def func2():
print(age)
age = 73
func2()
func1() #
#func2在执行之前age已经被重新赋值了,所以打印的是73
作用域:
在python中函数就是一个作用域
代码定义完成后,作用域已经生成,作用域链向上查找
匿名函数:
def calc(x,y):
return x*y lambda x,y:x*y #声明一个匿名函数 #上面这两个函数执行效果是一样的,但是第二个函数不好执行,如果想执行需要将它赋给一个变量,如下: func=lambda x,y:x*y #赋给一个变量之后这样就好执行了 print(func(3,8)) # ############################################################################################# def calc(x,y):
if x<y:
return x*y
else:
return x/y #lambda不支持复杂的逻辑语句,像上面这样就不行,lambda支持最复杂的就是三元运算,匿名本质上就是把多行语句变成了一行 func=lambda x,y:x*y if x<y else x/y print(func(16,8)) #2.0 #匿名函数主要一个作用就是和其它一些方法搭配使用(像上面这样匿名函数赋值给一个变量,和普通函数没什么区别) def f2(n):
return n*n print(list(map(f2,data))) #用普通函数实现乘方
print(list(map(lambda x:x*x,data))) #map函数的作用就是将后面的参数一个一个放入前面的函数执行。 #匿名函数的作用:
#1.节省代码量
#2.看着高级
深入分析:
# ---CASE 1
fs = map(lambda i:(lambda j: i*j), range(6))
print([f(2) for f in fs]) #---CASE 2
fs = [lambda j:i*j for i in range(6)]
print([f(2) for f in fs]) #---CASE 3
fs = []
for i in range(6):
fs.append(lambda j:i*j)
if i==3:
break
print([f(2) for f in fs]) #---CASE 4
fs = [(lambda i:lambda j:i*j)(i) for i in range(6)]
print([f(2) for f in fs])
搞会这几题只需弄懂一个问题,lambda函数是否执行并且在什么时候执行。
递归:函数在执行的过程中执行自己。
import sys
print(sys.getrecursionlimit()) #默认递归深度
sys.setrecursionlimit(1500) #设置递归深度 def resursion(n):
print(n)
resursion(n+1) resursion(1)
为什么要限制递归深度?
简单的理解就是递归函数执行之后,之前执行的所有函数都没有结束,这样会占用大量的内存空间,最终把内存撑爆。
深层次的理解就是函数的栈帧的关系。
递归的作用:用来解决复杂的数学问题,比如斐波那契数列、汉诺塔、多级评论数、二分查找、求阶乘等
求阶乘:
任何大于1自然数n阶乘表示方法:
n! = 1*2*3*4...*n
n! = n*(n-1)!
内置函数:
eval() 执行括号内的字符串,如果是代码或运算就执行,但只能执行一行代码,多行无法执行,它可以拿到返回值,但是无法执行函数。
exec() 可以执行多行代码,如果代码中有函数,这个函数是拿不到返回值的,也就是说只能执行,但没有结果。
code='''
def foo():
print("run foo")
return 1234
foo()
''' #这个函数必须顶行写,不然报错!!!
res=exec(code) #run foo
print(res) #none,也就是说exec没有返回值 print(eval("1+3+6+8")) #18,虽然eval不能执行多行代码,但是通过此方法还是能证明它有返回值。
print(exec("1+3+6+8")) #None,再次证明exec没有返回值
ord() 查看字符的ASCII码
chr() 将看ASCII码编号对应的字符
print(ord("a")) #
print(chr(97)) #a
sum() 求和
a=[100,-33,-22,180,30]
print(sum(a)) #
print()
msg="又回到最初的起点"
msg2="记忆中你青涩的脸"
f=open("那些年.txt","w",encoding="utf8")
print(msg,msg2,end="",sep="|",file=f) #又回到最初的起点|记忆中你青涩的脸
dir() 打印当前程序的变量名
vars() 打印当前程序的变量名和变量值
locals() 打印当前局部变量的变量名和变量值
globals() 打印全局变量名和变量值
print(dir()) #['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
print(vars()) #{'__spec__': None, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Lowry/PycharmProjects/lufyy/dir_var.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000000060E3C8>, '__doc__': None, '__name__': '__main__', '__cached__': None, '__package__': None}
print(locals()) #如果在全局,结果同上,如果在函数里面,那么只打印局部变量和变量值
print(globals()) #不论在哪,都是只打印全局变量名和变量值
round() 保留几位小数
print(round(1.22234342,2)) #1.22 保留两位小数
装饰器:
写一个装饰器
生成器:
列表生成式:li = [ i*i for i in range(10) ] 这个生成的是一个列表
这种生成式用法只能用在列表或元组里
斐波那契
只要函数里面有yield,这个函数名()就变成了一个生成器,无论里面有没有return。
return在生成器里,代表生成器的中止,直接报错。
next
唤醒生成器并断续执行
send
唤醒并继续执行
发送一个信息到生成器内部
def range2(n):
count=0
while count<n:
count+=1
sign=yield count
if sign=="stop":
break g=range2(10)
print(next(g))
print(next(g))
g.send("stop")
print(next(g))
迭代器:
可直接用于for循环的数据类型有以下几种:
一类是集合数据类型,如 list、tuple、dict、set、str 等
一类是generator ,包括生成器和带yield的generator function。
可以直接用于for循环的对象统称为可迭代对象:iterable
可使用instance()判断一个对象是不是iterable对象
from collections import Iterable #Iterable第一个字母必须要大写 print(isinstance([],Iterable)) #True
而生成器不但可以被for循环,还可以被next()函数调用并返回下一个值,直到最后抛出stopiteration错误表示无法继续
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator (只要满足这个条件的都迭代器,生成器只是迭代器的一种)
可使用instance()判断一个对象是不是iterator对象
from collections import Iterator print(isinstance((i for i in range(10)),Iterator)) #True print(isinstance([],Iterator)) #False
小结:
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterbtor类型,它们表示一个惰性计算序列
集合数据类型如list、dict、str乖都是Iterable但不是Iterbtor,不过可以通过iter()函数将可迭代对象变成迭代器对象。
python3的for循环本质上就是通过不断调用next()函数实现的。
路飞学城-Python开发集训-第3章的更多相关文章
- 路飞学城-Python开发集训-第1章
学习体会: 在参加这次集训之前我自己学过一段时间的Python,看过老男孩的免费视频,自我感觉还行,老师写的代码基本上都能看懂,但是实际呢?....今天是集训第一次交作业的时间,突然发现看似简单升级需 ...
- 路飞学城-Python开发集训-第4章
学习心得: 学习笔记: 在python中一个py文件就是一个模块 模块好处: 1.提高可维护性 2.可重用 3.避免函数名和变量名冲突 模块分为三种: 1.内置标准模块(标准库),查看所有自带和第三方 ...
- 路飞学城-Python开发集训-第2章
学习心得: 这章对编码的讲解超级赞,现在对于编码终于有一点认知了,但还没有大彻大悟,还需要更加细心的琢磨一下Alex博客和视频,以前真的是被编码折磨死了,因为编码的问题而浪费的时间很多很多,现在终于感 ...
- 路飞学城-Python开发集训-第5章
面向过程:核心是过程二字,过程是解决问题的步骤,相当于设计一条流水线,是机械式的思维方式 优点:复杂的问题流程化,进而简单化 缺点:可扩展性差 面向对象:核心是对象二字,对象就是特征与技能的结合体. ...
- 路飞学城-Python爬虫集训-第三章
这个爬虫集训课第三章的作业讲得是Scrapy 课程主要是使用Scrapy + Redis实现分布式爬虫 惯例贴一下作业: Python爬虫可以使用Requests库来进行简单爬虫的编写,但是Reque ...
- 路飞学城-Python开发-第一章
# 基础需求: # 让用户输入用户名密码 # 认证成功后显示欢迎信息 # 输错三次后退出程序 username = 'pandaboy' password = ' def Login(username ...
- 路飞学城-Python爬虫集训-第一章
自学Python的时候看了不少老男孩的视频,一直欠老男孩一个会员,现在99元爬虫集训果断参与. 非常喜欢Alex和武Sir的课,技术能力超强,当然讲着讲着就开起车来也说明他俩开车的技术也超级强! 以上 ...
- 路飞学城-Python爬虫集训-第二章
本次爬虫集训的第二次作业是web微信. 先贴一下任务: 作业中使用到了Flask. Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSGI 工具箱采用 Werkzeug ,模 ...
- 路飞学城-Python开发-第二章
''' 数据结构: menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, '汽车之家' ...
随机推荐
- 如何去除vue项目中的 # --- History模式
来自:https://www.cnblogs.com/zhuzhenwei918/p/6892066.html 侵删 使用vue-cli搭建的环境,在配置好路由之后,可以看到下面的情况: 但是不难发现 ...
- js 中prototype运用(数组)
转自:http://www.cnblogs.com/chiname/articles/216517.html(侵删) /* * 方法:Array.removeAt(Index) * 功能 ...
- CSS3 - @keyframes
语法 @keyframes animationname { keyframes-selector {css-styles;} } 值 描述 animationname 必需.定义动画的名称. keyf ...
- 使用JDBC连接MySQL数据库的一个基本案例
JDBC的概念(摘自百度百科) JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一 ...
- testNG安装一直失败解决方法
1.在eclipse界面选择“Help”--"Eclipse Marketplace"中进行查找TestNG 然后进“install” (成功) 2.在eclipse界面选择“He ...
- Kotlin入门教程——目录索引
Kotlin是谷歌官方认可的Android开发语言,Android Studio从3.0版本开始就内置了Kotlin,所以未来在App开发中Kotlin取代Java是大势所趋,就像当初Android ...
- Spark MLlib线性回归代码实现及结果展示
线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析. 这种函数是一个或多个称为回归系数的模型参数的线性组合.只有 ...
- CentOS6.8下MySQL MHA架构搭建笔记
转载请注明出处,本文地址:http://www.cnblogs.com/ajiangg/p/6552855.html 以下是CentOS6.8下MySQL MHA架构搭建笔记 IP资源规划: 192. ...
- SQLSERVER查询数据库死锁的存储过程
USE [IdentityDemo] GO /****** Object: StoredProcedure [dbo].[sp_who_lock] Script Date: 2019/1/17 10: ...
- 利用python搭建Powersploit powershell脚本站点
powershell脚本站点的搭建 一.Powersploit Powersploit是一款基于powershell的后渗透(Post-Exploitation)框架,集成大量渗透相关模块和功能. 下 ...