阿羚 发表于 2018-6-27 10:18:36

小甲鱼 发表于 2014-1-11 16:24
等于的话走else:分支,临界并不算超界

   就是说如果向右移动130步,为什么要让位置是(70,0),而不是走到100步时就停在100步位置是(100,0)呢?难道是走到100步后又倒回去走,直到走够130步为止?可方向就发生变化了,不符合向右移动啊

mingfang 发表于 2018-6-28 18:05:01

大菜蛋 发表于 2018-6-29 20:00:43

yu_wind 发表于 2014-1-11 16:55
我估计是我没看明白咋么移动的,
我的理解是, x轴上原来-80 往左挪30变成-110然后 if的结果是-90 ...

对,是的。从左边撞墙后从右边出来。

taotao8346 发表于 2018-6-30 09:14:30

yu_wind 发表于 2014-1-11 16:22
请问
if new_x < legal_x:
            pos_x = legal_x - (new_x - legal_x)


撞完墙往回走

学学看看 发表于 2018-7-3 11:18:21

王达沛 发表于 2018-7-18 11:27:21

本帖最后由 王达沛 于 2018-7-18 11:31 编辑

在看了小甲鱼的《零基础入门学习Python》的闭包函数后进了帖子观摩,
书本上的网址完全是错的,所以直接百度官网后注册搜索,才能进来,
估计是防止某些人恶意破坏,注册新账号后禁止发帖半个小时,,,

这代码本来我也看不懂,后来复制到Python3.65后,结合运行结果大概看明白了

先看 move = create() ,后面的调用方式是 move( 【1,0】,10 )
等价于create()( 【1,0】,10 ) ,create() 函数有默认形参,所以相当于
create( pos_x = 0 ,pos_y =0)( direction = [ 1, 0] , step = 10 )
第一个括号为 原点(0,0),第二个括号 为闭包:内部函数 moving( direction = [ 1, 0] , step = 10 )
的调用,在函数moving() 中 ,声明了 nonlocal pos_x, pos_y , 表明 pos_x, pos_y 属于
外部作用域:create() 中,即调用其原点位置。

在闭包中对全局变量 (列表list 类型 ) legal_x , legal_y 进行访问(没有进行修改哦),假如
移动后的新坐标 (x,y):new_x,new_y 超出了规定的范围 legal_x , legal_y 则多出部分往反方向
移动, 即 最大的 x 坐标 为 100,当向右移动 300 时, 最终停留位置: pos_x = 100 - (300 - 100)= -100
超出的 200 ,变成向左移动 200,(如果超过300小甲鱼这个程序的结果就溢出规定范围了哦!)
list列表变量 direction 的含义是 : direction【0】 左右移动(0 左,1 右),direction【1】 上下移动
(0 下,1 上),返回值为终点: pos_x, pos_y自动打包为元组的 (pos_x, pos_y)形式返回

所以 move( , 400 ) = create( pos_x = 0 ,pos_y =0)( direction = [ 0, 1] , step = 400 )
意思为 从原点 ( pos_x = 0 ,pos_y =0)向上移动( 因为 direction【1】 = 1)400(step 移动步幅)

以上就是我个人的浅见了,初学请包容,谢谢

735919873 发表于 2018-7-18 20:38:29

书中说“在闭包中,外部函数的局部变量对应内部函数的局部变量”
比如这个例子:
def funX(x):
      def funY(y):
         return x * y
      return funY
意思是funX(x)里面的x的值等于funY(y)中的y吗?

735919873 发表于 2018-7-18 20:45:37

上边的
move = create()
print('向右移动10步后,位置是:', move(, 10))

虽然reate(pos_x=0, pos_y=0)里面的两个形参已有默认初值,但是move引用时候,怎么会跳过对pos_x,pos_y的赋值而直接对序列direction进行赋值?起码 '向右移动10步的赋值应该是 move(某个值, 某个值, , 10)' 这样子吧?

mathnawi 发表于 2018-7-22 21:28:46

向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 70)
向上移动130步为什么位置是(10,70),不该是(0,70)吗?

mathnawi 发表于 2018-7-22 21:54:41

mathnawi 发表于 2018-7-22 21:28
向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 7 ...

在执行语句:print('向右移动10步后,位置是:', move(, 10))   之后pos_x的值已经变成了10,
执行语句:print('向上移动130步后,位置是:', move(, 130))之后pos_x=10,pos_y=70
再执行语句:print('向左移动10步后,位置是:', move([-1, 0], 10))时,过程为:
new_x = pos_x + direction * step==》new_x =10+(-1)*10即new_x=0
new_y = pos_y + direction * step==》new_y =70+0*10即 new_y=70

Mezzomax 发表于 2018-7-25 22:13:48

王达沛 发表于 2018-7-18 11:27
在看了小甲鱼的《零基础入门学习Python》的闭包函数后进了帖子观摩,
书本上的网址完全是错的,所以直接百 ...

总体思路没错 但是我觉得最后的结论说的不准确
按照你图上的命令 move( , 400 ) 应该等于create(pos_x = 10, pos_y = 0)(direction = , step = 400)这里的pos_x 和 pos_y已经在上一步里面被赋值了 除非你在运行完第一个print之后重新运行一遍move = create() 否则pos_x和pos_y 不会初始化。
另外这个程序还有缺点 就是边界判断在步数超过300后 会出现如下结果

move = create()
print(move(, 302))
(0, -102)

所以还需要加入pos_x pos_y 的边界判定

HONORz 发表于 2018-7-30 23:10:53

1

loverggn 发表于 2018-8-2 14:33:35

闭包函数的作用在于:每次调用闭包函数(moving)都可以共享上一次调用moving函数所形成的“环境”结果,
这个环境指的就是外部函数的变量即nonlocal pos_x, pos_y。本例中pos_x,pos_y这组变量表明了当前位置状
态即人物所在坐标,而下一次的闭包函数moving调用会基于上次形成的坐标继续移动,形成新的坐标环境。
这就是闭包函数机制的作用。
再从闭包函数的调用机制上看,有人些认为:内部函数返回的元组return pos_x, pos_y直接被外部函数返回
(return moving),于是就认为调用create()得到的返回值是元组(pos_x, pos_y),这种理解是不对的!事实
上,外部函数create中的return的是“对内部函数对象的引用”,通过这个函数对象的引用才能继续反复多次的
调用内部函数,即move=create()得到的move是个函数对象引用,其指向的是闭包函数moving,通过move
对象可以多次调用moving函数并传以不同的参数(move(, 10)....)

loverggn 发表于 2018-8-2 14:43:43

阿羚 发表于 2018-6-27 10:18
就是说如果向右移动130步,为什么要让位置是(70,0),而不是走到100步时就停在100步位置是(100, ...

这个只是作者设定的游戏规则,就是让人物反弹回去,不必在意{:5_109:}

ZKD 发表于 2018-8-3 19:03:25

这个就是走到头然后再往回走的,如果设定为撞墙之后从另外一边出来的话在临界条件赋值取一个相反数就行了

jeffjg 发表于 2018-8-11 14:07:06

这个太高端了我怎么一点也看不懂啊

致年轻的我们 发表于 2018-8-14 11:18:57

原来看不懂,今天再回来看,看懂了,博大精深啊。

hao123lcm 发表于 2018-8-14 11:33:00

小甲鱼是天才程序员啊{:5_108:}

橙子2 发表于 2018-8-17 18:31:31

当move被重新赋值之后,pose_x,pose_y 没有被初始化为0,而是在前面的基础上继续计算得到的,为什么呀?

橙子2 发表于 2018-8-17 18:35:13

xiawb 发表于 2014-3-26 13:59
>>>
向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)


向右移动10步后,位置是: (10, 0)
向上移动130步后,位置是: (10, 70)
向左移动10步后,位置是: (0, 70)
move参数改变没有重置pose_x 和pose_y 的初始值,这个的运行结果就是上面所示,why?
页: 4 5 6 7 8 9 10 11 12 13 [14] 15 16 17 18 19 20 21 22 23
查看完整版本: 游戏中的角色移动:闭包(closure)在实际开发中的作用