Python逻辑控制流
所谓逻辑控制流,就是控制程序的逻辑行为,一步一步的流向,可以使用流程图来表现这种行为的流动。控制流一般分成正常控制流和异常控制流,正常就是一切按预期的方向发展,异常就是控制流的突变。
*基于python 3.6.2 tutorial整理
python逻辑控制
- 条件语句
- 循环语句
- 异常控制
- function(可重用逻辑语句的封装)
if条件
if statement :
pass
elif stat:
pass
elif stat:
pass
else:
pass
循环
for i in <iterable object>:
pass
###
while stat:
pass
#range()方法,产生数字序列
range(from,to,step)
range(10) >> [0,1,2,3,4,5,6,7,8,9]
range(1,5) >> [1,2,3,4]
range(1,10,2)>>[1,3,5,7,9]
异常控制
try:
#do something dangerous
except Exception as e:
# do something save
#<else>:
pass
#<finally>: always execute this block
pass
方法
- 方法定义
# via https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions
def functionname(args):
pass
def func(a:str) #指定参数类型
- 方法参数
普通参数
def func(a,b):
pass
带默认参数(也叫关键字参数),调用时b可不传
def func(a,b=10):
pass
可变参数--------
#a、b之后的参数由c接收,多个参数则c为list对象
def func(a,b,*c):
pass
# c接收多个dict形式的参数,
def func(a,b,**c):
pass
# 可变参数应该是最后一个参数,要么最后的是默认参数。*args 和**args共存时,**在后面
def concat(*args, sep="/"):
# Unpacking Argument Lists
# 1.
list(range(3, 6)) # normal call with separate arguments
#[3, 4, 5]
args = [3, 6]
list(range(*args)) # call with arguments unpacked from a list
# 2.
def parrot(voltage, state='a stiff', action='voom')
#unpacking map obejct to args
d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d)
####################################
error example:
def func(a=10,b):
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print("-- This parrot wouldn't", action, end=' ')
print("if you put", voltage, "volts through it.")
print("-- Lovely plumage, the", type)
print("-- It's", state, "!")
parrot() # invalid :required argument missing
parrot(voltage=5.0, 'dead') #invalid: non-keyword argument after a keyword argument
parrot(voltage=5.0) # valid
parrot(110, voltage=220) # invalid:duplicate value for the same argument
parrot(actor='John Cleese') # invalid:unknown keyword argument
- 参数传递
python的参数是对象传递,如果对象是不可变的(immutable),则传递的是字面量,即为传值;如果对象是可变的(mutable),则传递的是引用。
#for example
# mutable object => list object,immutable object str object
def modify(li: list, s: str):
s = "modify"
li[0] = "modify"
list0 = [1, 2, 3]
str0 = "howareu"
print(list0,str0) # [1, 2, 3] howareu
modify(list0, str0)
print(list0,str0) # ['modify', 2, 3] howareu
java中参数的传递,和python其实差不多,不可变的传值,可变的传地址(地址值,也是值),所以说java参数是传值的。O'Reilly's Java in a Nutshell by David Flanagan (see Resources) puts it best: "java manipulates objects 'by reference,' but it passes object references to methods 'by value.'"这个value就是地址的value。
- 方法内变量查找
方法内定义的变量,叫局部变量,或者叫本地变量(local variable),其分配存储在local symbol table中。当在方法内引用一个变量的时候,变量的查找路径是:local symbol table --->global symbol table--->build-in names.
所以,如果在方法内定义了一个和外部(方法外)名字一样的变量,就会遮蔽外部变量,当然不会修改,只是遮蔽,使得方法内只能看到这个local变量。
- 变量的scope规则和namespace
namespace:a mapping from a name to object;是一种关系的映射,类比文件的路径,如果以一个文件为基准,则可以通过相对路径和绝对路径,去定位一个唯一的文件,这个路径,就是一个namespace。和不同目录下的同名文件之间没有关联类似,不同namespace的的变量,也是无关的。
变量的scope,可以类比文件目录的层次来理解。namespace类比文件所在目录的名字加上文件名,scope则是这个文件的活动区域,作用空间,可见范围。
如在主要一个多层次的目录下:
/tmp/---
---dir01/
---a.py # namespace: /tmp/dir01/a.py | scope:/tmp/dir01/
---b.py # namespace: /tmp/dir01/b.py | scope:/tmp/dir01/
---diir02/
---a.py # namespace: /tmp/dir02/a.py | scope:/tmp/dir02/
---b.py # namespace: /tmp/dir02/a.py | scope:/tmp/dir02/
---a.py # namespace: /tmp/a.py | scope:/tmp/
---b.py # namespace: /tmp/a.py | scope:/tmp/
在一个目录下,只能看到目录里面的文件,这个可见范围,可以理解成scope。越在外层,越能被更多的视野扫描到。
而改变一个变量(文件)的scope,就是移动这个文件,python提供了两个statement,来修改变量的scope。
- nonlocal <var>
- global <var>
* nonlocal:是把变量的作用域,绑定到外一层的scope中去,但不会是global;
* global:则是绑定到global全局scope中去,让所有的人都能看到它的身影。
- lambda表达式
lambda表达式可用来定义一个匿名函数。在python中有诸多限制,使用场景在于去代替只有一句语句的 function定义。不是很推荐使用。
func = lambda x: x + 1
print(func(1))
def make_incrementor(n):
return lambda x: x + n
f = make_incrementor(42)
f(0) # 42
The end.