免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2886 | 回复: 9
打印 上一主题 下一主题

求助高手:改写一个Perl函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-14 18:28 |只看该作者 |倒序浏览
近日在《Learn Perl》中发现perl 5.10引入了一个关键字state,类似于C语言里的static变量。其中有一个函数用到了这个特点,于是想用Python实现类似的效果,耗时甚多却毫无头绪,特向各位求助。

原Perl函数:

use 5.010;

sub running_sum {
  state $sum = 0;
  state @numbers;
  foreach my $number ( @_ ) {
    push @numbers, $number;
    $sum += $number;
  }
  say "The sum of (@numbers) is $sum";
}

调用函数:
running_sum( 5, 6 );
running_sum( 1..3 );
running_sum( 4 );


改写成Python调用,则为如下格式:
running_sum( 5, 6 )
running_sum( [1, 2, 3] )
running_sum( 4 )


则程序输出为:
The sum of (5 6) is 11
The sum of (5 6 1 2 3) is 17
The sum of (5 6 1 2 3 4) is 21

如果允许使用全局变量,那么其实很简单;因此不能使用全局变量。
如果使用class,大概也不太难实现,不过我没试验过。

如果只用函数改写,而不用到class,可能需要用到如下知识:
1. 变长函数参数,类似于 def func(a, b, *args, **kargs). Perl调用时,参数会自动解嵌套成一个变长的非嵌套的list;而Python的参数则可能嵌套。当然简单起见,只要实现上述变长非嵌套参数调用即可。  (-:
2. generators. 但是generator函数只是在执行期间保留状态,而原Perl程序则是多次调用函数。因此我的想法是在Python版的函数体内使用 while true 形式的死循环.


期待高手出手....

论坛徽章:
0
2 [报告]
发表于 2009-01-15 09:19 |只看该作者
sum = 0
def run_sum(a, b, *args):
    global sum
    sum += a + b
    for i in args:
        sum += i

if __name__=='__main__':
    run_sum(1,2)
    print sum
    run_sum(3,4,1,2)
    print sum

论坛徽章:
0
3 [报告]
发表于 2009-01-15 10:27 |只看该作者

  1. >>>def test(*args):
  2. ...     if not hasattr(test,'total'):test.total=0
  3. ...     test.total +=sum( [ type(v) is tuple or type(v) is list and sum(v) or v for v in args ])
  4. ...     return test.total
  5. ...
  6. >>> test(1,2,3)
  7. 6
  8. >>> test([1,2,3],4,5,6)
  9. 27
  10. >>> test(1)
  11. 28
复制代码

评分

参与人数 1可用积分 +5 收起 理由
xiaoyu9805119 + 5 我很赞同

查看全部评分

论坛徽章:
0
4 [报告]
发表于 2009-01-15 11:05 |只看该作者
我对Python不熟说的不对别骂我。。。
在perl5.10之前都是利用闭包间接实现静态变量的

  1. {
  2.   my $count;
  3.   sub foo{print $count++;}
  4. }
复制代码

Python 也有类似的做法.

  1. def foo():
  2.   count = [1]
  3.   def bar():
  4.     count[0] += 1
  5.     return count[0]
  6.   return bar
  7. bar = foo()
  8. print bar()
  9. print bar()
复制代码

论坛徽章:
0
5 [报告]
发表于 2009-01-15 12:48 |只看该作者

回复 #4 DQP 的帖子

突然想我想起perl宣称的解决问题的办法不止一种
py也有很多种

论坛徽章:
0
6 [报告]
发表于 2009-01-16 10:33 |只看该作者
为啥不能用全局变量呢

论坛徽章:
0
7 [报告]
发表于 2009-01-16 10:45 |只看该作者
global 就是全局的啊

论坛徽章:
0
8 [报告]
发表于 2009-01-17 12:11 |只看该作者
如我在要求里说的,如果使用全局变量,那么就很容易实现了。我是想看看Python用什么方法也可以实现Perl、C中的static类型的变量。
因此,二楼的方法其实是不符合要求的,呵呵
其实《Learn Python》一书中也提到了类似的解答方法,除了使用class外,另外两种办法就是三楼和四楼两位的解决办法了。
此外,似乎使用generator语法并不能达到我想要的目的   ):

论坛徽章:
0
9 [报告]
发表于 2009-01-17 12:12 |只看该作者
原帖由 xiaoyu9805119 于 2009-1-15 12:48 发表
突然想我想起perl宣称的解决问题的办法不止一种
py也有很多种


对一个问题,通常情况下,Python都不会只有一种解法;但是,直观简单的解法往往只有一种  

论坛徽章:
0
10 [报告]
发表于 2009-01-17 18:08 |只看该作者
python的全局变量其实是模块级变量,与传统意义上的全局变量不同。应该充分利用,不必排斥。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP