JerryZH
发表于 2018-3-29 10:21:12
发现了一个问题,好像并没有初始化为0啊,都是在上一步的位置上移动的
jasonpy
发表于 2018-3-30 22:35:33
本帖最后由 jasonpy 于 2018-3-30 22:43 编辑
个人的一些学习心得,希望能帮助到看不懂的鱼友们
origin = (0, 0) # 原点
legal_x = [-100, 100] # x轴的移动范围
legal_y = [-100, 100] # y轴的移动范围
def create(pos_x=0, pos_y=0):
# 初始化位于原点为主
def moving(direction, step):
# direction参数设置方向,1为向右(向上),-1为向左(向下),0为不移动
# step参数设置移动的距离
nonlocal pos_x, pos_y #强制pos为非局部变量,可记录
print('initial value pos_x: ',pos_x)
print('initial valu pos_y: ',pos_y)
new_x = pos_x + direction * step
new_y = pos_y + direction * step
# 检查移动后是否超出x轴边界
if new_x < legal_x:
pos_x = legal_x - (new_x - legal_x)
elif new_x > legal_x:
pos_x = legal_x - (new_x - legal_x)
else:
pos_x = new_x
# 检查移动后是否超出y轴边界
if new_y < legal_y:
pos_y = legal_y - (new_y - legal_y)
elif new_y > legal_y:
pos_y = legal_y - (new_y - legal_y)
else:
pos_y = new_y
print('final value pos_x: ',pos_x)
print('final valu pos_y: ',pos_y)
return pos_x, pos_y # return 这里是让moving这个function输出pos_x,pos_y
#pos_x and pos_y are global virables, here specify nonlocal
return moving
move = create() # move is a function type that returns the closure function//
# move(direction, step)
print('向右移动10步后,位置是:', move(, 10))
print('向上移动130步后,位置是:', move(, 130))
print('向左移动10步后,位置是:', move([-1, 0], 10))
# pos_x pos_y is not defined globally.....!!!
个人的一些研究,上面的代码加上几个注释后会输出以下,也就是说闭包很大的一个好处就是可以记住历史,这个用一般方程比较难做到。。
initial value pos_x:0
initial valu pos_y:0
final value pos_x:10
final valu pos_y:0
向右移动10步后,位置是: (10, 0)
initial value pos_x:10
initial valu pos_y:0
final value pos_x:10
final valu pos_y:70
向上移动130步后,位置是: (10, 70)
initial value pos_x:10
initial valu pos_y:70
final value pos_x:0
final valu pos_y:70
向左移动10步后,位置是: (0, 70)
我尝试了一下不用闭包写一段比较容易明白的代码:
origin = (0, 0) # 原点
legal_x = [-100, 100] # x轴的移动范围
legal_y = [-100, 100] # y轴的移动范围
tempos_x = 0
tempos_y = 0
def moving(direction, step):
# direction参数设置方向,1为向右(向上),-1为向左(向下),0为不移动
# step参数设置移动的距离
#nonlocal pos_x, pos_y #强制pos为非局部变量
global tempos_x, tempos_y
pos_x = tempos_x #设置起始值
pos_y = tempos_y #设置起始值
new_x = pos_x + direction * step
new_y = pos_y + direction * step
# 检查移动后是否超出x轴边界
if new_x < legal_x:
pos_x = legal_x - (new_x - legal_x)
elif new_x > legal_x:
pos_x = legal_x - (new_x - legal_x)
else:
pos_x = new_x
# 检查移动后是否超出y轴边界
if new_y < legal_y:
pos_y = legal_y - (new_y - legal_y)
elif new_y > legal_y:
pos_y = legal_y - (new_y - legal_y)
else:
pos_y = new_y
tempos_x = pos_x
tempos_y = pos_y
return pos_x, pos_y
#pos_x and pos_y are global virables, here specify nonlocal
#return moving
#move = create() # move is a function type that returns the closure function//
# move(direction, step)
print('向右移动10步后,位置是:',moving(,10))
print('向上移动130步后,位置是:',moving(,130))
print('向左移动10步后,位置是:',moving([-1, 0],10))
# if use this function, then it can't remember pos_x and pos_y..
#..need to manually define the last positon to return the same results...
同样,这个会输出一样的结果:
向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 70)
显而,第二段代码是比较“低级”的也更容易明白的,明白了后,就知道闭包的好处啦,就是可以非常简单的“记忆”,只需要定义一个“nonlocal”,就可以有记忆功能了,也不需要定义全局变量。希望这个可以帮助到看不懂的人
白昼
发表于 2018-4-1 12:39:24
66666666,赞一个
18166893221
发表于 2018-4-11 15:50:43
关于每次都会初始化的理解:
有两个关键知识点:
1.函数中的默认参数值:
当某些函数需要有默认输入(即提前设定好缺省值)可用以下格式:
def myfun(x=缺省值):
print(x)
2.闭包函数(函数中的函数)的调用:
example:
def test1():
def test2():
print('sucessful')
return test2()
def test1_1():
def test2_2():
print('bingo')
return test2_2
如果需要访问test2以及test2_2,则分别输入test1()以及test1_1()()。
而此程序中,move=create(),相当于move已经调用了create(位置1)(位置2)的位置一,而且位置一使用了默认值(pos_x=0,pos_y=0),这样相当于通过move()这种操作把一个闭包函数脱掉了一层衣服。在需要调用的时候,只需要输入里面那层衣服需要的值就好。
如果要是type(move)的话可以发现其返回值是function类型。
当然也可以试试 test=create(2,2)(,1),这样也是有输出结果的。
wstczzh
发表于 2018-4-13 22:00:27
666
彩虹七号
发表于 2018-4-24 11:33:33
看不懂 ,长路漫漫呀
向日葵4444
发表于 2018-4-27 19:40:40
yu_wind 发表于 2014-1-11 16:22
请问
if new_x < legal_x:
pos_x = legal_x - (new_x - legal_x)
等于的不算超出边界,在else里 就行
theendofen
发表于 2018-4-29 11:19:29
新手,,,,,看不懂。。。。。。
hbinn
发表于 2018-5-9 13:24:53
能复制否
STmove
发表于 2018-5-19 14:45:05
IDLE返回:SyntaxError: multiple statements found while compiling a single statement
查了下是说我在一行里写了多行的代码,是版本的问题么,我装的是3.4.1
zhdwinter
发表于 2018-5-22 21:35:14
guokai83524 发表于 2014-3-17 13:05
看不懂最后的调用30-33行,为什么move里面可以这样带参数,不理解
因为move = create()之后,move 就相当于将内部函数moving了
zhdwinter
发表于 2018-5-22 21:37:23
为什么每次动作完之后需要强制将pos_x和pos_y强制归零呢,为什么不能在上次位置的基础上进行移动呢
chengjun079
发表于 2018-5-23 09:41:43
ddddddddd
糖妖妖66
发表于 2018-5-28 14:46:59
yu_wind 发表于 2014-1-11 16:22
请问
if new_x < legal_x:
pos_x = legal_x - (new_x - legal_x)
假设 pos_x等于legal_x 那么 if 里面 改写一下 变成pos_x+new_x = legal_x【0】+legal_x
因为pos_x等于legal_x 所以消掉那么久变成new_x = legal_x了如果 new_x= legal_x就不会进if了 应该进 else 毕竟你的if条件是 new_x < legal_x
akyl56
发表于 2018-5-31 11:18:21
顶
小白要成神
发表于 2018-6-8 15:57:10
yu_wind 发表于 2014-1-11 16:55
我估计是我没看明白咋么移动的,
我的理解是, x轴上原来-80 往左挪30变成-110然后 if的结果是-90 ...
我觉得也是,撞完墙会退回来
tglovell
发表于 2018-6-10 23:30:34
想问一下:28行return moving没有看懂,moving不是一个变量,那返回的是什么呢,是将这个函数运行一遍吗。还有move到底是一个函数还是变量呢。move运行之后的返回结果moving到底是什么形式呢?
cable
发表于 2018-6-20 12:00:02
还没明白,学完20课再来学
www.4399whs
发表于 2018-6-21 01:10:54
小甲鱼哥哥能赠送一点鱼币吗,好想做课后习题却没有鱼币,内心十分纠结呢,下个月我就可以开会员了,这个月实在囊中羞涩
阿羚
发表于 2018-6-27 10:11:31
小甲鱼 发表于 2014-1-11 16:24
等于的话走else:分支,临界并不算超界
可是else:分支不是pos_x = new_x吗?为什么if new_x < legal_x时,不直接pox_x=legal_x呢?