前言
- 初学Python,姑妄言之,如有错误之处,恳请留言区指正
一、选择结构
1、条件表达式
#代码示例
if 3: print(True) #数字作为条件表达式
if "abc": print(True) #非空字符串作为条件表达式
s=[] #空列表作为条件表达式
if s: print(True)
else: print(False)
i=s=0 #比较表达式作为条件表达式
while i<=10: s+=i; i+=1
print(s)
i=s=0 #True作为条件表达式 永真循环
while True:
s+=i; i+=1; if i>10: break
print(s)
s=0
for i in range(0,11,1): s+=i #遍历序列元素 in表达式作为条件表达式
print(s)
print(3 and 5) #and前式不为0则会计算后式,为0则不计算后式
print(0 and 5)
print(3 or 5) #or前式为0则计算后式,不为0则不计算后式
print(0 or 5)
#运行结果
True
True
False
55
55
55
5
0
3
5
2、选择结构的几种形式
Ⅰ、单分支选择结构?
if 表达式: 语句块(短的话可以用";"隔开写在一行)
Ⅱ、双分支选择结构?
if 表达式: 语句块? ? ? ? #满足条件表达式执行
else: 语句块? ? ? ? ? ? ? #不满足条件表达式执行
扩展知识:Python提供三元运算符:value1 if condition else value2,也具有惰性求值的特点;?
Ⅲ、 多分支选择结构
if 表达式1: 语句块1? ? ? ? ?#满足表达式1执行语句块1
elif 表达式2: 语句块2? ? ? ?#满足表达式2执行语句块2
……
else: 语句块3? ? ? ? ? ? ? ? ? ?#不满足上面所有表达式执行语句块3
Ⅳ、选择结构的嵌套?
if 外表达式1: 外语句块1
? ? ? ? if??内表达式1: 内语句块1
? ? ? ? else: 内语句块2
else: 外语句块2?
注意要点:使用嵌套选择结构时,一定要严格控制好不同级别代码块的缩进量;?
二、循环结构?
1、for循环与while循环的基本语法
while循环形式:?
while 表达式: 循环体
[else:? 语句块]? ? ? ? ? #当循环带有else语句时,在循环表达式不成立或者遍历结束而自然结束时执行,当break出循环时不执行
for循环形式:
for 取值 in 序列或迭代对象: 循环体?
[else:? 语句块]? ? ? ? ? #当循环带有else语句时,在循环表达式不成立或者遍历结束而自然结束时执行,当break出循环时不执行
友情提示:在编程时一般优先考虑for循环?
2、break与continue语句?
区别:
break是跳出循环语句,直接结束循环
continue结束本次循环,并忽略continue之后的所有语句,回到循环顶端,进入下次循环?
#代码示例?
for i in range(0,10,1): #在{0……10}循环
if i==4: continue #当到4时跳过本次循环,不执行后面的语句
if i==8: break #当到8时结束for循环,不执行后面的语句
print(i,end=',') #打印i
i+=1
print("\n")
i=0
while i<=10: #在{0……10}循环
if i==6: continue #当到6时跳过本次循环,
if i==5: break #当到5时结束while循环,不再执行后面的语句
print(i,end=',') #打印i
i+=1
#运行结果
0,1,2,3,5,6,7,
0,1,2,3,4,
?分析:for循环在4时跳过本次循环未执行打印操作,在8时直接结束for循环,因此8,9都未打印;while循环在5时直接结束while循环,因此5,6,7,8,9,10都未执行打印操作;
循环代码优化技巧?
- 减少循环内不必要或无关的计算;
- 在多重循环嵌套的情况中,尽量减少内层循环中不必要的操作;
- 在循环中尽量引用局部变量,局部变量的访问比全局变量略快;?
三、函数设计与使用?
????????函数表示从自变量到因变量之间的一种映射关系,软件开发中,可能许多操作都是重复的,这样我们可以编写函数来减小代码耦合度,实现更好的代码复用;
1、基本语法?
def 函数名 ([参数列表]) :? ? ? ? ? ? ? ? ? ?#多个参数之间应用逗号隔开
? ? ? ? ’‘’注释‘’‘? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#可有可无、尽量简短明了
? ? ? ? 函数体
?#定义函数时需要注意的问题
- 函数形参不需要声明其类型,也不需要指定其返回类型(与C、C++、java完全不同);
- 即使函数不需要接受任何参数,也必须保留一对空的圆括号;
- 括号后面的冒号必不可少;
- 函数体相对于def关键字必须保持一定的空格缩进;(在Python中通过空格缩进表示内外层关系,相对于java、C++、C等以"{ }"与";"表示有很大的不同,另如果两个表达式很c写在同一行,那么需要以";"分隔且在最后一个表达式后不用";"结尾;)
- Python中注释符为" #注释 "与不在任何内容中的"? '''注释'''? "
#代码示例
#运行结果?
2、Python函数设计中不得不说的那些事儿??
Ⅰ、返回值?
- Python定义函数时不需要声明返回值类型,而是用return直接返回任意类型的值,函数返回值类型与return语句返回表达式的类型一致。如果没有return语句或执行不返回任何值的return语句,则默认返回None(空值);注意:无论return在什么位置,一旦执行return语句将直接结束函数的执行;
- 调用函数时一定要注意函数有没有返回值以及是否会对函数的值进行修改。例如:列表对象的sort()方法属于原地排序操作,而内置函数sorted()则新返回一个排好序的列表;
#代码示例
a_list=[1,3,5,2,4,6]
print("soorted()的返回值:",sorted(a_list))
print("执行了sorted()后:",a_list)
print("sort()的返回值:",a_list.sort())
print("执行sort()后a_list:",a_list)
#运行结果?
soorted()的返回值: [1, 2, 3, 4, 5, 6]
执行了sorted()后: [1, 3, 5, 2, 4, 6]
sort()的返回值: None
执行sort()后a_list: [1, 2, 3, 4, 5, 6]
Ⅱ、嵌套函数的使用(在Python中函数是可以嵌套定义的)?
在Python中,函数是可调用对象,是可以嵌套定义的,而且由于构造函数的存在,类也是可以调用的,任何包含_ _call_ _()方法的类的对象都是可以调用的。(有点难懂,直接上代码)?
#代码示例?
'''函数嵌套定义的实例'''
def linear (a,b):
def result(x): return a*x+b
return result
test1=linear(2,3)
print("test1的类型:",type(test1))
print(test1(4))
'''包含__call__方法的类'''
class linear:
def __init__(self,a,b): self.a, self.b = a, b
def __call__(self,x): return self.a * x + self.b
test2=linear(2,3)
print("test2的类型:",type(test2))
print(test2(4))
#运行结果?
test1的类型: <class 'function'>
11
test2的类型: <class '__main__.linear'>
11
? ? ? ? 结果分析:由结果我们可以理解为test1是被赋值了linear(2,3)返回了的result方法,此时的test1就是自带两个私有常量a,b的result方法;
Ⅲ、函数参数?
- 一般来说在函数内部修改形参值不会改变传进实参的值,当然,有特殊情况,当传递给函数的是Python可变序列,并且在函数内部使用下标或序列自身支持的方式增删改时,会影响到实参的值;(可以在函数内用global声明使用全局变量从而修改函数外的变量值)
- 默认值参数:Python支持默认值参数,即在定义函数时为形参设置默认值,在调用有默认值参数的函数时可以不用为设置了默认值的形参进行传值;?可以使用"函数名._ _defaults_ _"来随时查看函数所有默认值参数的当前值;注意:当使用列表作为默认参数,由于其可记忆性,连续多次调用该函数而不给该参数传值时,二次调用会保留上一次调用的结果(改变方法:加if语句恢复默认)
- 关键参数:主要指调用函数时的参数传递方式,与函数定义无关。与C、Java等不同的是Python可以按参数的名字传值,实参顺序可以和形参不同,避免了记顺序的麻烦;
- 可变长度的参数:主要有两种形式:*parameter 与 **parameter,前者用于接受任意多个实参并放在一个元组里,后者接受类似于关键参数一样的显式赋值形参存于字典里;
- 传递参数时的序列解包:?在调用含有多个参数的函数时,可以使用列表、元组等可迭代对象作为实参,但需要在其前面加个" * ",解释器自动解包,然后传递给形参;注意:①字典作为实参时默认使用“键”,如需要使用值需调用字典的values()方法说明;②实参中元素个数与形参个数必须相等,否则会报错;③如果对实参使用一个(*),那这些解包后的实参会被当成普通位置参数对待,并且会在关键参数和使用(**)进行序列解包的参数之前处理;
#代码示例?
print("demo1")
'''编写函数实现对传进来的参数加1并打印操作'''
def demo1(a):a+=1;print(a)
b=1
demo1(b) #传入实参
print(b) #打印验证是否改变
print("\ndemo2")
'''编写有默认参数值函数实现对列表的增操作并返回列表'''
def demo2(new,olist=[]):olist.append(new);return olist
print("参数为('a')时:",demo2('a')) #对demo()函数的三次连续不传默认值参数的调用
print("参数为('6')时:",demo2('6'))
print("参数为('3')时:",demo2('3'))
print("参数为('12',[1,2])时:",demo2('12',[1,2]))
print("参数为('7')时:",demo2('7'))
print("\ndemo3")
'''编写有三个参数的函数,实现对参数的按序打印,验证关键参数知识点'''
def demo3(a,b,c=0):print(a,b,c)
demo3(1,2) #按序传入两个参数
demo3(1,2,3) #按序传入三个参数(对有默认值参数进行传值)
demo3(b=3,a=4) #按形参名传入两个参数
demo3(c=5,a=3,b=2) #按形参名传入三个参数(对有默认值参数进行传值)
print("\ndemo4")
'''验证可变长度参数知识点'''
def demo4(*p):print(p) #验证单值型参数
demo4(1,2,3,4,5) #调用函数,传入任意个参数
print("\ndemo5")
def demo5(**p):print(p) #验证类似于关键参数型参数
demo5(a=1,b=2,c=3,d=4) #调用函数,传入任意个关键参数
print("\ndemo6")
'''验证序列解包知识点'''
def demo6(a,b,c):print(a,b,c)
demo6(*[4,2,3])
demo6(1,*(4,5)) #先顺序赋值不用解包的1,再解包后顺序赋值,所以a=1,b=4,c=5
#demo6(a=1,*(1,2)) #会报错,先进行序列解包再关键参数,解包后先给a,b赋值,后关键参数又给a赋值造成报错
#demo6(**{'a':1,'b':2},*[3]) #会报错,关键参数解包不能再*序列解包之后
#demo6(*[3],**{'a':1,'b':2}) #会报错,先*序列解包给a赋值,再关键参数解包给a,b赋值,重复赋值,导致报错
demo6(*[3],**{'c':1,'b':2}) #正确运行,*序列解包给a赋值,再关键序列解包给b,c赋值,所结果为3 2 1
#运行结果?
demo1
2
1
demo2
参数为('a')时: ['a']
参数为('6')时: ['a', '6']
参数为('3')时: ['a', '6', '3']
参数为('12',[1,2])时: [1, 2, '12']
参数为('7')时: ['a', '6', '3', '7']
demo3
1 2 0
1 2 3
4 3 0
3 2 5
demo4
(1, 2, 3, 4, 5)
demo5
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
demo6
4 2 3
1 4 5
3 2 1
Ⅳ、变量作用域 (变量起作用的代码范围叫做变量作用域)
- ?不同作用域内同名变量之间互不影响(就像不同文件夹下的同名文件),如果在函数内使用该同名变量则以局部变量为主(就近原则);
- 在函数内部声明的叫做局部变量,在函数外声明的叫做全局变量;局部变量在函数被调用完之后会被自动删除,全局变量在调用完函数后还有效;
- 某变量在函数外定义,如果想在函数内需要修改其值并反应在函数外,可以用global声明一个已存在的同名全局变量;
- 在函数内用global将一个变量声明为全局变量,如果之前没有定义该全局变量,那么在调用该函数后会自动增加该全局变量;
- 不同模块共享变量则需要导入才可修改或者访问;
小知识点:?
- 一般而言局部变量的引用比全局变量速度快,优先考据使用;尽量减少全局变量的使用,全局变量会增加不用函数之间的耦合度,降低代码可读性;
- 局部变量的空间是在栈上分配的,而栈空间是由操作系统维护的,每调用一个函数,系统为其奉派一个栈帧,函数第哦啊用结束立刻释放该栈帧,因此,函数调用结束之后,函数内部的局部变量就不存在了;
- 除了局部变量和全局变量之外,Python还有一个介于全局与局部之间的用nonlocal声明的变量。
#代码示例?
'''验证变量作用域的函数'''
def scope_test():
def do_local():
spam = "我是局部变量"
def do_nonlocakl():
nonlocal spam
spam = "我是nonlocal变量"
def do_global():
global spam #全局没有spam变量则创建新的spam全局变量
spam = "我是全局变量" #给全局变量赋值
spam = "原来的值"
do_local() #外层对于内层来说就是全局变量
print("局部变量赋值后:",spam) #因为局部变量不改变全局变量的值,所以spam值不改变
do_nonlocakl() #nonlocal将变量spam变为nonlocal型变量,所以值改变
print("nonlocal变量赋值后:",spam) #spam现在可以当作另类的全局变量而又不是全局变量
do_global() #全局变量里没有spam变量,所以在此函数里创建了新的spam全局变量
print("全局变量赋值后:",spam) #根据就近原则,在此引用nonlocal的spam变量
scope_test() #调用上面函数
print("全局变量:",spam) #打印spam的全局变量值
#运行结果?
局部变量赋值后: 原来的值
nonlocal变量赋值后: 我是nonlocal变量
全局变量赋值后: 我是nonlocal变量
全局变量: 我是全局变量
Ⅴ、函数设计综合应用?
代码功能:check_permission(func)方法用于对传进来的函数进行添加用户名检验功能,Read类用来封装文件读写方法,并以check_permission(func)装饰或调用;
'''要在D盘下创建sample.txt文件才能运行哦,也可以修改下面d:\sample.txt'''
'''为函数增加检验输入username参数的值,不正确抛出异常,正确原样返回'''
def check_permission(func): #传入一个函数参数
def wrapper(*args,**kargs):
if kargs.get('username')!='admin':
raise Exception("sorry")
return func(*args,**kargs)
return wrapper #将函数封装为一个wrapper方法,调用该函数相当于调用wrapper方法
class Read(object):
#@是作为装饰器调用函数与作为普通函数调用效果一样
#@check_permission
def read(self,username,filemame):
return open(filemame,'r').read()
read=check_permission(read) #作为普通函数调用
@check_permission
def write(self,username,filename,content):
open(filename,'a+').write(content)
#write=check_permission(write)
t=Read()
print('Originally……')
print(t.read(username='admin',filemame=r'd:\sample.txt'))
print('now,try to write to a file……')
t.write(username='admin',filename=r'd:\sample.txt',content='\nhelllo world')
print('After call to write……')
print(t.read(username='admin',filemame=r'd:\sample.txt'))
运行结果:?
Originally……
now,try to write to a file……
After call to write……
helllo world
三、? ?lambda表达式
lambda表达式常用来声明匿名函数,即没有函数名的函数,通常只用一次;
lambda表达式只可以包含一个表达式,不允许包含复杂的语句,但可以调用其他的函数,并支持默认值参数和关键参数,该表达式的计算结果相当于函数的返回值。
语法形式:
lambda 参数 : 表达式
#代码示例
g = lambda a=1,b=2,c=3:a+b+c #g被赋值一个lambda函数,把g当作函数使用
print(g(5)) #为a赋值5,所以输出结果为9
L=[(labdma x:x),(labdma x:x+1),(labdma x:x+2),(labdma x:x+3)] #相当于4个函数
print(L[0](1),L[1](1),)L[2](1),L[3](1)) #运行结果为1,2,3,4
小提示:lambda表达式的熟悉与灵活运用对你的代码编写很有帮助哦!
|